add a visual low time warning (tiny change from Debian patches)
[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 xpmPieceBitmap[4][(int)BlackPawn];       /* LL, LD, DL, DD */
499 Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
500 int useImages, useImageSqs;
501 XImage *ximPieceBitmap[4][(int)BlackPawn];      /* LL, LD, DL, DD */
502 Pixmap ximMaskPm[(int)BlackPawn];            /* clipmasks, used for XIM pieces */
503 XImage *ximLightSquare, *ximDarkSquare;
504 XImage *xim_Cross;
505
506 #define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % (int)BlackPawn]
507 #define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % (int)BlackPawn]
508
509 #define White(piece) ((int)(piece) < (int)BlackPawn)
510
511 /* Variables for doing smooth animation. This whole thing
512    would be much easier if the board was double-buffered,
513    but that would require a fairly major rewrite.       */
514
515 typedef struct {
516         Pixmap  saveBuf;
517         Pixmap  newBuf;
518         GC      blitGC, pieceGC, outlineGC;
519         XPoint  startSquare, prevFrame, mouseDelta;
520         int     startColor;
521         int     dragPiece;
522         Boolean dragActive;
523         int     startBoardX, startBoardY;
524     } AnimState;
525
526 /* There can be two pieces being animated at once: a player
527    can begin dragging a piece before the remote opponent has moved. */
528
529 static AnimState game, player;
530
531 /* Bitmaps for use as masks when drawing XPM pieces.
532    Need one for each black and white piece.             */
533 static Pixmap xpmMask[BlackKing + 1];
534
535 /* This magic number is the number of intermediate frames used
536    in each half of the animation. For short moves it's reduced
537    by 1. The total number of frames will be factor * 2 + 1.  */
538 #define kFactor    4
539
540 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
541
542 MenuItem fileMenu[] = {
543     {N_("New Game"), ResetProc},
544     {N_("New Shuffle Game ..."), ShuffleMenuProc},
545     {N_("New Variant ..."), NewVariantProc},      // [HGM] variant: not functional yet
546     {"----", NothingProc},
547     {N_("Load Game"), LoadGameProc},
548     {N_("Load Next Game"), LoadNextGameProc},
549     {N_("Load Previous Game"), LoadPrevGameProc},
550     {N_("Reload Same Game"), ReloadGameProc},
551     {N_("Save Game"), SaveGameProc},
552     {"----", NothingProc},
553     {N_("Copy Game"), CopyGameProc},
554     {N_("Paste Game"), PasteGameProc},
555     {"----", NothingProc},
556     {N_("Load Position"), LoadPositionProc},
557     {N_("Load Next Position"), LoadNextPositionProc},
558     {N_("Load Previous Position"), LoadPrevPositionProc},
559     {N_("Reload Same Position"), ReloadPositionProc},
560     {N_("Save Position"), SavePositionProc},
561     {"----", NothingProc},
562     {N_("Copy Position"), CopyPositionProc},
563     {N_("Paste Position"), PastePositionProc},
564     {"----", NothingProc},
565     {N_("Mail Move"), MailMoveProc},
566     {N_("Reload CMail Message"), ReloadCmailMsgProc},
567     {"----", NothingProc},
568     {N_("Exit"), QuitProc},
569     {NULL, NULL}
570 };
571
572 MenuItem modeMenu[] = {
573     {N_("Machine White"), MachineWhiteProc},
574     {N_("Machine Black"), MachineBlackProc},
575     {N_("Two Machines"), TwoMachinesProc},
576     {N_("Analysis Mode"), AnalyzeModeProc},
577     {N_("Analyze File"), AnalyzeFileProc },
578     {N_("ICS Client"), IcsClientProc},
579     {N_("Edit Game"), EditGameProc},
580     {N_("Edit Position"), EditPositionProc},
581     {N_("Training"), TrainingProc},
582     {"----", NothingProc},
583     {N_("Show Engine Output"), EngineOutputProc},
584     {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
585     {N_("Show Game List"), ShowGameListProc},
586     {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
587     {"----", NothingProc},
588     {N_("Edit Tags"), EditTagsProc},
589     {N_("Edit Comment"), EditCommentProc},
590     {N_("ICS Input Box"), IcsInputBoxProc},
591     {N_("Pause"), PauseProc},
592     {NULL, NULL}
593 };
594
595 MenuItem actionMenu[] = {
596     {N_("Accept"), AcceptProc},
597     {N_("Decline"), DeclineProc},
598     {N_("Rematch"), RematchProc},
599     {"----", NothingProc},
600     {N_("Call Flag"), CallFlagProc},
601     {N_("Draw"), DrawProc},
602     {N_("Adjourn"), AdjournProc},
603     {N_("Abort"), AbortProc},
604     {N_("Resign"), ResignProc},
605     {"----", NothingProc},
606     {N_("Stop Observing"), StopObservingProc},
607     {N_("Stop Examining"), StopExaminingProc},
608     {"----", NothingProc},
609     {N_("Adjudicate to White"), AdjuWhiteProc},
610     {N_("Adjudicate to Black"), AdjuBlackProc},
611     {N_("Adjudicate Draw"), AdjuDrawProc},
612     {NULL, NULL}
613 };
614
615 MenuItem stepMenu[] = {
616     {N_("Backward"), BackwardProc},
617     {N_("Forward"), ForwardProc},
618     {N_("Back to Start"), ToStartProc},
619     {N_("Forward to End"), ToEndProc},
620     {N_("Revert"), RevertProc},
621     {N_("Truncate Game"), TruncateGameProc},
622     {"----", NothingProc},
623     {N_("Move Now"), MoveNowProc},
624     {N_("Retract Move"), RetractMoveProc},
625     {NULL, NULL}
626 };
627
628 MenuItem optionsMenu[] = {
629     {N_("Flip View"), FlipViewProc},
630     {"----", NothingProc},
631     {N_("Adjudications ..."), EngineMenuProc},
632     {N_("General Settings ..."), UciMenuProc},
633     {N_("Engine #1 Settings ..."), FirstSettingsProc},
634     {N_("Engine #2 Settings ..."), SecondSettingsProc},
635     {N_("Time Control ..."), TimeControlProc},
636     {"----", NothingProc},
637     {N_("Always Queen"), AlwaysQueenProc},
638     {N_("Animate Dragging"), AnimateDraggingProc},
639     {N_("Animate Moving"), AnimateMovingProc},
640     {N_("Auto Comment"), AutocommProc},
641     {N_("Auto Flag"), AutoflagProc},
642     {N_("Auto Flip View"), AutoflipProc},
643     {N_("Auto Observe"), AutobsProc},
644     {N_("Auto Raise Board"), AutoraiseProc},
645     {N_("Auto Save"), AutosaveProc},
646     {N_("Blindfold"), BlindfoldProc},
647     {N_("Flash Moves"), FlashMovesProc},
648     {N_("Get Move List"), GetMoveListProc},
649 #if HIGHDRAG
650     {N_("Highlight Dragging"), HighlightDraggingProc},
651 #endif
652     {N_("Highlight Last Move"), HighlightLastMoveProc},
653     {N_("Move Sound"), MoveSoundProc},
654     {N_("ICS Alarm"), IcsAlarmProc},
655     {N_("Old Save Style"), OldSaveStyleProc},
656     {N_("Periodic Updates"), PeriodicUpdatesProc},
657     {N_("Ponder Next Move"), PonderNextMoveProc},
658     {N_("Popup Exit Message"), PopupExitMessageProc},
659     {N_("Popup Move Errors"), PopupMoveErrorsProc},
660     {N_("Premove"), PremoveProc},
661     {N_("Quiet Play"), QuietPlayProc},
662     {N_("Show Coords"), ShowCoordsProc},
663     {N_("Hide Thinking"), HideThinkingProc},
664     {N_("Test Legality"), TestLegalityProc},
665     {NULL, NULL}
666 };
667
668 MenuItem helpMenu[] = {
669     {N_("Info XBoard"), InfoProc},
670     {N_("Man XBoard"), ManProc},
671     {"----", NothingProc},
672     {N_("Hint"), HintProc},
673     {N_("Book"), BookProc},
674     {"----", NothingProc},
675     {N_("About XBoard"), AboutProc},
676     {NULL, NULL}
677 };
678
679 Menu menuBar[] = {
680     {N_("File"), fileMenu},
681     {N_("Mode"), modeMenu},
682     {N_("Action"), actionMenu},
683     {N_("Step"), stepMenu},
684     {N_("Options"), optionsMenu},
685     {N_("Help"), helpMenu},
686     {NULL, NULL}
687 };
688
689 #define PAUSE_BUTTON N_("P")
690 MenuItem buttonBar[] = {
691     {"<<", ToStartProc},
692     {"<", BackwardProc},
693     {PAUSE_BUTTON, PauseProc},
694     {">", ForwardProc},
695     {">>", ToEndProc},
696     {NULL, NULL}
697 };
698
699 #define PIECE_MENU_SIZE 11
700 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
701     { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
702       N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
703     { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
704       N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
705 };
706 /* must be in same order as PieceMenuStrings! */
707 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
708     { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
709         WhiteRook, WhiteQueen, WhiteKing,
710         (ChessSquare) 0, EmptySquare, ClearBoard },
711     { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
712         BlackRook, BlackQueen, BlackKing,
713         (ChessSquare) 0, EmptySquare, ClearBoard },
714 };
715
716 #define DROP_MENU_SIZE 6
717 String dropMenuStrings[DROP_MENU_SIZE] = {
718     "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
719   };
720 /* must be in same order as PieceMenuStrings! */
721 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
722     (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
723     WhiteRook, WhiteQueen
724 };
725
726 typedef struct {
727     char piece;
728     char* widget;
729 } DropMenuEnables;
730
731 DropMenuEnables dmEnables[] = {
732     { 'P', "Pawn" },
733     { 'N', "Knight" },
734     { 'B', "Bishop" },
735     { 'R', "Rook" },
736     { 'Q', "Queen" }
737 };
738
739 Arg shellArgs[] = {
740     { XtNwidth, 0 },
741     { XtNheight, 0 },
742     { XtNminWidth, 0 },
743     { XtNminHeight, 0 },
744     { XtNmaxWidth, 0 },
745     { XtNmaxHeight, 0 }
746 };
747
748 Arg layoutArgs[] = {
749     { XtNborderWidth, 0 },
750     { XtNdefaultDistance, 0 },
751 };
752
753 Arg formArgs[] = {
754     { XtNborderWidth, 0 },
755     { XtNresizable, (XtArgVal) True },
756 };
757
758 Arg boardArgs[] = {
759     { XtNborderWidth, 0 },
760     { XtNwidth, 0 },
761     { XtNheight, 0 }
762 };
763
764 Arg titleArgs[] = {
765     { XtNjustify, (XtArgVal) XtJustifyRight },
766     { XtNlabel, (XtArgVal) "..." },
767     { XtNresizable, (XtArgVal) True },
768     { XtNresize, (XtArgVal) False }
769 };
770
771 Arg messageArgs[] = {
772     { XtNjustify, (XtArgVal) XtJustifyLeft },
773     { XtNlabel, (XtArgVal) "..." },
774     { XtNresizable, (XtArgVal) True },
775     { XtNresize, (XtArgVal) False }
776 };
777
778 Arg timerArgs[] = {
779     { XtNborderWidth, 0 },
780     { XtNjustify, (XtArgVal) XtJustifyLeft }
781 };
782
783 XtResource clientResources[] = {
784     { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
785         XtOffset(AppDataPtr, whitePieceColor), XtRString,
786         WHITE_PIECE_COLOR },
787     { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
788         XtOffset(AppDataPtr, blackPieceColor), XtRString,
789         BLACK_PIECE_COLOR },
790     { "lightSquareColor", "lightSquareColor", XtRString,
791         sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
792         XtRString, LIGHT_SQUARE_COLOR },
793     { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
794         XtOffset(AppDataPtr, darkSquareColor), XtRString,
795         DARK_SQUARE_COLOR },
796     { "highlightSquareColor", "highlightSquareColor", XtRString,
797         sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
798         XtRString, HIGHLIGHT_SQUARE_COLOR },
799     { "premoveHighlightColor", "premoveHighlightColor", XtRString,
800         sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
801         XtRString, PREMOVE_HIGHLIGHT_COLOR },
802     { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
803         XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
804         (XtPointer) MOVES_PER_SESSION },
805     { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
806         XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
807         (XtPointer) TIME_INCREMENT },
808     { "initString", "initString", XtRString, sizeof(String),
809         XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
810     { "secondInitString", "secondInitString", XtRString, sizeof(String),
811         XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
812     { "firstComputerString", "firstComputerString", XtRString,
813         sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
814       COMPUTER_STRING },
815     { "secondComputerString", "secondComputerString", XtRString,
816         sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
817       COMPUTER_STRING },
818     { "firstChessProgram", "firstChessProgram", XtRString,
819         sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
820         XtRString, FIRST_CHESS_PROGRAM },
821     { "secondChessProgram", "secondChessProgram", XtRString,
822         sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
823         XtRString, SECOND_CHESS_PROGRAM },
824     { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
825         sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
826         XtRImmediate, (XtPointer) False },
827     { "noChessProgram", "noChessProgram", XtRBoolean,
828         sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
829         XtRImmediate, (XtPointer) False },
830     { "firstHost", "firstHost", XtRString, sizeof(String),
831         XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
832     { "secondHost", "secondHost", XtRString, sizeof(String),
833         XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
834     { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
835         XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
836     { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
837         XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
838     { "bitmapDirectory", "bitmapDirectory", XtRString,
839         sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
840         XtRString, "" },
841     { "remoteShell", "remoteShell", XtRString, sizeof(String),
842         XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
843     { "remoteUser", "remoteUser", XtRString, sizeof(String),
844         XtOffset(AppDataPtr, remoteUser), XtRString, "" },
845     { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
846         XtOffset(AppDataPtr, timeDelay), XtRString,
847         (XtPointer) TIME_DELAY_QUOTE },
848     { "timeControl", "timeControl", XtRString, sizeof(String),
849         XtOffset(AppDataPtr, timeControl), XtRString,
850         (XtPointer) TIME_CONTROL },
851     { "internetChessServerMode", "internetChessServerMode",
852         XtRBoolean, sizeof(Boolean),
853         XtOffset(AppDataPtr, icsActive), XtRImmediate,
854         (XtPointer) False },
855     { "internetChessServerHost", "internetChessServerHost",
856         XtRString, sizeof(String),
857         XtOffset(AppDataPtr, icsHost),
858         XtRString, (XtPointer) ICS_HOST },
859     { "internetChessServerPort", "internetChessServerPort",
860         XtRString, sizeof(String),
861         XtOffset(AppDataPtr, icsPort), XtRString,
862         (XtPointer) ICS_PORT },
863     { "internetChessServerCommPort", "internetChessServerCommPort",
864         XtRString, sizeof(String),
865         XtOffset(AppDataPtr, icsCommPort), XtRString,
866         ICS_COMM_PORT },
867     { "internetChessServerLogonScript", "internetChessServerLogonScript",
868         XtRString, sizeof(String),
869         XtOffset(AppDataPtr, icsLogon), XtRString,
870         ICS_LOGON },
871     { "internetChessServerHelper", "internetChessServerHelper",
872         XtRString, sizeof(String),
873         XtOffset(AppDataPtr, icsHelper), XtRString, "" },
874     { "internetChessServerInputBox", "internetChessServerInputBox",
875         XtRBoolean, sizeof(Boolean),
876         XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
877         (XtPointer) False },
878     { "icsAlarm", "icsAlarm",
879         XtRBoolean, sizeof(Boolean),
880         XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
881         (XtPointer) True },
882     { "icsAlarmTime", "icsAlarmTime",
883         XtRInt, sizeof(int),
884         XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
885         (XtPointer) 5000 },
886     { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
887         XtOffset(AppDataPtr, useTelnet), XtRImmediate,
888         (XtPointer) False },
889     { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
890         XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
891     { "gateway", "gateway", XtRString, sizeof(String),
892         XtOffset(AppDataPtr, gateway), XtRString, "" },
893     { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
894         XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
895     { "loadGameIndex", "loadGameIndex",
896         XtRInt, sizeof(int),
897         XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
898         (XtPointer) 0 },
899     { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
900         XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
901     { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
902         sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
903         XtRImmediate, (XtPointer) True },
904     { "autoSaveGames", "autoSaveGames", XtRBoolean,
905         sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
906         XtRImmediate, (XtPointer) False },
907     { "blindfold", "blindfold", XtRBoolean,
908         sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
909         XtRImmediate, (XtPointer) False },
910     { "loadPositionFile", "loadPositionFile", XtRString,
911         sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
912         XtRString, "" },
913     { "loadPositionIndex", "loadPositionIndex",
914         XtRInt, sizeof(int),
915         XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
916         (XtPointer) 1 },
917     { "savePositionFile", "savePositionFile", XtRString,
918         sizeof(String), XtOffset(AppDataPtr, savePositionFile),
919         XtRString, "" },
920     { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
921         XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
922     { "matchGames", "matchGames", XtRInt, sizeof(int),
923         XtOffset(AppDataPtr, matchGames), XtRImmediate,
924         (XtPointer) 0 },
925     { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
926         XtOffset(AppDataPtr, monoMode), XtRImmediate,
927         (XtPointer) False },
928     { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
929         XtOffset(AppDataPtr, debugMode), XtRImmediate,
930         (XtPointer) False },
931     { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
932         XtOffset(AppDataPtr, clockMode), XtRImmediate,
933         (XtPointer) True },
934     { "boardSize", "boardSize", XtRString, sizeof(String),
935         XtOffset(AppDataPtr, boardSize), XtRString, "" },
936     { "searchTime", "searchTime", XtRString, sizeof(String),
937         XtOffset(AppDataPtr, searchTime), XtRString,
938         (XtPointer) "" },
939     { "searchDepth", "searchDepth", XtRInt, sizeof(int),
940         XtOffset(AppDataPtr, searchDepth), XtRImmediate,
941         (XtPointer) 0 },
942     { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
943         XtOffset(AppDataPtr, showCoords), XtRImmediate,
944         (XtPointer) False },
945     { "showJail", "showJail", XtRInt, sizeof(int),
946         XtOffset(AppDataPtr, showJail), XtRImmediate,
947         (XtPointer) 0 },
948     { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
949         XtOffset(AppDataPtr, showThinking), XtRImmediate,
950         (XtPointer) True },
951     { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
952         XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
953         (XtPointer) True },
954     { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
955         XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
956         (XtPointer) True },
957     { "clockFont", "clockFont", XtRString, sizeof(String),
958         XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
959     { "coordFont", "coordFont", XtRString, sizeof(String),
960         XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
961     { "font", "font", XtRString, sizeof(String),
962         XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
963     { "ringBellAfterMoves", "ringBellAfterMoves",
964         XtRBoolean, sizeof(Boolean),
965         XtOffset(AppDataPtr, ringBellAfterMoves),
966         XtRImmediate, (XtPointer) False },
967     { "autoCallFlag", "autoCallFlag", XtRBoolean,
968         sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
969         XtRImmediate, (XtPointer) False },
970     { "autoFlipView", "autoFlipView", XtRBoolean,
971         sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
972         XtRImmediate, (XtPointer) True },
973     { "autoObserve", "autoObserve", XtRBoolean,
974         sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
975         XtRImmediate, (XtPointer) False },
976     { "autoComment", "autoComment", XtRBoolean,
977         sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
978         XtRImmediate, (XtPointer) False },
979     { "getMoveList", "getMoveList", XtRBoolean,
980         sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
981         XtRImmediate, (XtPointer) True },
982 #if HIGHDRAG
983     { "highlightDragging", "highlightDragging", XtRBoolean,
984         sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
985         XtRImmediate, (XtPointer) False },
986 #endif
987     { "highlightLastMove", "highlightLastMove", XtRBoolean,
988         sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
989         XtRImmediate, (XtPointer) False },
990     { "premove", "premove", XtRBoolean,
991         sizeof(Boolean), XtOffset(AppDataPtr, premove),
992         XtRImmediate, (XtPointer) True },
993     { "testLegality", "testLegality", XtRBoolean,
994         sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
995         XtRImmediate, (XtPointer) True },
996     { "flipView", "flipView", XtRBoolean,
997         sizeof(Boolean), XtOffset(AppDataPtr, flipView),
998         XtRImmediate, (XtPointer) False },
999     { "cmail", "cmailGameName", XtRString, sizeof(String),
1000         XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
1001     { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
1002         sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
1003         XtRImmediate, (XtPointer) False },
1004     { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
1005         sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
1006         XtRImmediate, (XtPointer) False },
1007     { "quietPlay", "quietPlay", XtRBoolean,
1008         sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
1009         XtRImmediate, (XtPointer) False },
1010     { "titleInWindow", "titleInWindow", XtRBoolean,
1011         sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
1012         XtRImmediate, (XtPointer) False },
1013     { "localLineEditing", "localLineEditing", XtRBoolean,
1014         sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
1015         XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
1016 #ifdef ZIPPY
1017     { "zippyTalk", "zippyTalk", XtRBoolean,
1018         sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
1019         XtRImmediate, (XtPointer) ZIPPY_TALK },
1020     { "zippyPlay", "zippyPlay", XtRBoolean,
1021         sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
1022         XtRImmediate, (XtPointer) ZIPPY_PLAY },
1023     { "zippyLines", "zippyLines", XtRString, sizeof(String),
1024         XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
1025     { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
1026         XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
1027     { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
1028         XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
1029     { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
1030         XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
1031     { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
1032         XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
1033         ZIPPY_WRONG_PASSWORD },
1034     { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
1035         XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
1036     { "zippyUseI", "zippyUseI", XtRBoolean,
1037         sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
1038         XtRImmediate, (XtPointer) ZIPPY_USE_I },
1039     { "zippyBughouse", "zippyBughouse", XtRInt,
1040         sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
1041         XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
1042     { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
1043         sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
1044         XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
1045     { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
1046         XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
1047     { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
1048         XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
1049     { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
1050         sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
1051         XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
1052     { "zippyAbort", "zippyAbort", XtRBoolean,
1053         sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
1054         XtRImmediate, (XtPointer) ZIPPY_ABORT },
1055     { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
1056         XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
1057     { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
1058         XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
1059         (XtPointer) ZIPPY_MAX_GAMES },
1060     { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
1061         XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
1062         (XtPointer) ZIPPY_REPLAY_TIMEOUT },
1063     { "zippyShortGame", "zippyShortGame", XtRInt, sizeof(int),
1064         XtOffset(AppDataPtr, zippyShortGame), XtRImmediate,
1065         (XtPointer) 0 },
1066 #endif
1067     { "flashCount", "flashCount", XtRInt, sizeof(int),
1068         XtOffset(AppDataPtr, flashCount), XtRImmediate,
1069         (XtPointer) FLASH_COUNT  },
1070     { "flashRate", "flashRate", XtRInt, sizeof(int),
1071         XtOffset(AppDataPtr, flashRate), XtRImmediate,
1072         (XtPointer) FLASH_RATE },
1073     { "pixmapDirectory", "pixmapDirectory", XtRString,
1074         sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
1075         XtRString, "" },
1076     { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
1077         XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
1078         (XtPointer) MS_LOGIN_DELAY },
1079     { "colorizeMessages", "colorizeMessages", XtRBoolean,
1080         sizeof(Boolean), XtOffset(AppDataPtr, colorize),
1081         XtRImmediate, (XtPointer) False },
1082     { "colorShout", "colorShout", XtRString,
1083         sizeof(String), XtOffset(AppDataPtr, colorShout),
1084         XtRString, COLOR_SHOUT },
1085     { "colorSShout", "colorSShout", XtRString,
1086         sizeof(String), XtOffset(AppDataPtr, colorSShout),
1087         XtRString, COLOR_SSHOUT },
1088     { "colorChannel1", "colorChannel1", XtRString,
1089         sizeof(String), XtOffset(AppDataPtr, colorChannel1),
1090         XtRString, COLOR_CHANNEL1 },
1091     { "colorChannel", "colorChannel", XtRString,
1092         sizeof(String), XtOffset(AppDataPtr, colorChannel),
1093         XtRString, COLOR_CHANNEL },
1094     { "colorKibitz", "colorKibitz", XtRString,
1095         sizeof(String), XtOffset(AppDataPtr, colorKibitz),
1096         XtRString, COLOR_KIBITZ },
1097     { "colorTell", "colorTell", XtRString,
1098         sizeof(String), XtOffset(AppDataPtr, colorTell),
1099         XtRString, COLOR_TELL },
1100     { "colorChallenge", "colorChallenge", XtRString,
1101         sizeof(String), XtOffset(AppDataPtr, colorChallenge),
1102         XtRString, COLOR_CHALLENGE },
1103     { "colorRequest", "colorRequest", XtRString,
1104         sizeof(String), XtOffset(AppDataPtr, colorRequest),
1105         XtRString, COLOR_REQUEST },
1106     { "colorSeek", "colorSeek", XtRString,
1107         sizeof(String), XtOffset(AppDataPtr, colorSeek),
1108         XtRString, COLOR_SEEK },
1109     { "colorNormal", "colorNormal", XtRString,
1110         sizeof(String), XtOffset(AppDataPtr, colorNormal),
1111         XtRString, COLOR_NORMAL },
1112     { "soundProgram", "soundProgram", XtRString,
1113       sizeof(String), XtOffset(AppDataPtr, soundProgram),
1114       XtRString, "play" },
1115     { "soundShout", "soundShout", XtRString,
1116       sizeof(String), XtOffset(AppDataPtr, soundShout),
1117       XtRString, "" },
1118     { "soundSShout", "soundSShout", XtRString,
1119       sizeof(String), XtOffset(AppDataPtr, soundSShout),
1120       XtRString, "" },
1121     { "soundChannel1", "soundChannel1", XtRString,
1122       sizeof(String), XtOffset(AppDataPtr, soundChannel1),
1123       XtRString, "" },
1124     { "soundChannel", "soundChannel", XtRString,
1125       sizeof(String), XtOffset(AppDataPtr, soundChannel),
1126       XtRString, "" },
1127     { "soundKibitz", "soundKibitz", XtRString,
1128       sizeof(String), XtOffset(AppDataPtr, soundKibitz),
1129       XtRString, "" },
1130     { "soundTell", "soundTell", XtRString,
1131       sizeof(String), XtOffset(AppDataPtr, soundTell),
1132       XtRString, "" },
1133     { "soundChallenge", "soundChallenge", XtRString,
1134       sizeof(String), XtOffset(AppDataPtr, soundChallenge),
1135       XtRString, "" },
1136     { "soundRequest", "soundRequest", XtRString,
1137       sizeof(String), XtOffset(AppDataPtr, soundRequest),
1138       XtRString, "" },
1139     { "soundSeek", "soundSeek", XtRString,
1140       sizeof(String), XtOffset(AppDataPtr, soundSeek),
1141       XtRString, "" },
1142     { "soundMove", "soundMove", XtRString,
1143       sizeof(String), XtOffset(AppDataPtr, soundMove),
1144       XtRString, "$" },
1145     { "soundIcsWin", "soundIcsWin", XtRString,
1146       sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
1147       XtRString, "" },
1148     { "soundIcsLoss", "soundIcsLoss", XtRString,
1149       sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
1150       XtRString, "" },
1151     { "soundIcsDraw", "soundIcsDraw", XtRString,
1152       sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
1153       XtRString, "" },
1154     { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
1155       sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
1156       XtRString, "" },
1157     { "soundIcsAlarm", "soundIcsAlarm", XtRString,
1158       sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
1159       XtRString, "$" },
1160     { "reuseFirst", "reuseFirst", XtRBoolean,
1161         sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
1162         XtRImmediate, (XtPointer) True },
1163     { "reuseSecond", "reuseSecond", XtRBoolean,
1164         sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
1165         XtRImmediate, (XtPointer) True },
1166     { "animateDragging", "animateDragging", XtRBoolean,
1167         sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
1168         XtRImmediate, (XtPointer) True },
1169     { "animateMoving", "animateMoving", XtRBoolean,
1170         sizeof(Boolean), XtOffset(AppDataPtr, animate),
1171         XtRImmediate, (XtPointer) True },
1172     { "animateSpeed", "animateSpeed", XtRInt,
1173         sizeof(int), XtOffset(AppDataPtr, animSpeed),
1174         XtRImmediate, (XtPointer)10 },
1175     { "popupExitMessage", "popupExitMessage", XtRBoolean,
1176         sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
1177         XtRImmediate, (XtPointer) True },
1178     { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
1179         sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
1180         XtRImmediate, (XtPointer) False },
1181     { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
1182         sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
1183         XtRImmediate, (XtPointer)4 },
1184     { "initialMode", "initialMode", XtRString,
1185         sizeof(String), XtOffset(AppDataPtr, initialMode),
1186         XtRImmediate, (XtPointer) "" },
1187     { "variant", "variant", XtRString,
1188         sizeof(String), XtOffset(AppDataPtr, variant),
1189         XtRImmediate, (XtPointer) "normal" },
1190     { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
1191         sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
1192         XtRImmediate, (XtPointer)PROTOVER },
1193     { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
1194         sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
1195         XtRImmediate, (XtPointer)PROTOVER },
1196     { "showButtonBar", "showButtonBar", XtRBoolean,
1197         sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
1198         XtRImmediate, (XtPointer) True },
1199     { "lowTimeWarningColor", "lowTimeWarningColor", XtRString,
1200       sizeof(String), XtOffset(AppDataPtr, lowTimeWarningColor),
1201       XtRString, COLOR_LOWTIMEWARNING },
1202     { "lowTimeWarning", "lowTimeWarning", XtRBoolean,
1203       sizeof(Boolean), XtOffset(AppDataPtr, lowTimeWarning),
1204       XtRImmediate, (XtPointer) False },
1205     {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean,        /* [DM] icsEngineAnalyze */
1206         sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
1207         XtRImmediate, (XtPointer) False },
1208     { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
1209         sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
1210         XtRImmediate, (XtPointer) False },
1211     { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
1212         sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
1213         XtRImmediate, (XtPointer) False },
1214     { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
1215         sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
1216         XtRImmediate, (XtPointer) False },
1217     { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
1218         sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
1219         XtRImmediate, (XtPointer) True },
1220     { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
1221         sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
1222         XtRImmediate, (XtPointer) 0},
1223     { "pgnEventHeader", "pgnEventHeader", XtRString,
1224         sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
1225         XtRImmediate, (XtPointer) "Computer Chess Game" },
1226     { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
1227         sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
1228         XtRImmediate, (XtPointer) -1},
1229     { "gameListTags", "gameListTags", XtRString,
1230         sizeof(String), XtOffset(AppDataPtr, gameListTags),
1231         XtRImmediate, (XtPointer) GLT_DEFAULT_TAGS },
1232
1233     // [HGM] 4.3.xx options
1234     { "boardWidth", "boardWidth", XtRInt,
1235         sizeof(int), XtOffset(AppDataPtr, NrFiles),
1236         XtRImmediate, (XtPointer) -1},
1237     { "boardHeight", "boardHeight", XtRInt,
1238         sizeof(int), XtOffset(AppDataPtr, NrRanks),
1239         XtRImmediate, (XtPointer) -1},
1240     { "matchPause", "matchPause", XtRInt,
1241         sizeof(int), XtOffset(AppDataPtr, matchPause),
1242         XtRImmediate, (XtPointer) 10000},
1243     { "holdingsSize", "holdingsSize", XtRInt,
1244         sizeof(int), XtOffset(AppDataPtr, holdingsSize),
1245         XtRImmediate, (XtPointer) -1},
1246     { "flipBlack", "flipBlack", XtRBoolean,
1247         sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
1248         XtRImmediate, (XtPointer) False},
1249     { "allWhite", "allWhite", XtRBoolean,
1250         sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
1251         XtRImmediate, (XtPointer) False},
1252     { "pieceToCharTable", "pieceToCharTable", XtRString,
1253         sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
1254         XtRImmediate, (XtPointer) 0},
1255     { "alphaRank", "alphaRank", XtRBoolean,
1256         sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
1257         XtRImmediate, (XtPointer) False},
1258     { "testClaims", "testClaims", XtRBoolean,
1259         sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
1260         XtRImmediate, (XtPointer) True},
1261     { "checkMates", "checkMates", XtRBoolean,
1262         sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
1263         XtRImmediate, (XtPointer) True},
1264     { "materialDraws", "materialDraws", XtRBoolean,
1265         sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
1266         XtRImmediate, (XtPointer) True},
1267     { "trivialDraws", "trivialDraws", XtRBoolean,
1268         sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
1269         XtRImmediate, (XtPointer) False},
1270     { "ruleMoves", "ruleMoves", XtRInt,
1271         sizeof(int), XtOffset(AppDataPtr, ruleMoves),
1272         XtRImmediate, (XtPointer) 51},
1273     { "repeatsToDraw", "repeatsToDraw", XtRInt,
1274         sizeof(int), XtOffset(AppDataPtr, drawRepeats),
1275         XtRImmediate, (XtPointer) 6},
1276     { "engineDebugOutput", "engineDebugOutput", XtRInt,
1277         sizeof(int), XtOffset(AppDataPtr, engineComments),
1278         XtRImmediate, (XtPointer) 1},
1279     { "userName", "userName", XtRString,
1280         sizeof(int), XtOffset(AppDataPtr, userName),
1281         XtRImmediate, (XtPointer) 0},
1282     { "autoKibitz", "autoKibitz", XtRBoolean,
1283         sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
1284         XtRImmediate, (XtPointer) False},
1285     { "firstTimeOdds", "firstTimeOdds", XtRInt,
1286         sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
1287         XtRImmediate, (XtPointer) 1},
1288     { "secondTimeOdds", "secondTimeOdds", XtRInt,
1289         sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
1290         XtRImmediate, (XtPointer) 1},
1291     { "timeOddsMode", "timeOddsMode", XtRInt,
1292         sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
1293         XtRImmediate, (XtPointer) 0},
1294     { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
1295         sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
1296         XtRImmediate, (XtPointer) 1},
1297     { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
1298         sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
1299         XtRImmediate, (XtPointer) 1},
1300     { "firstNPS", "firstNPS", XtRInt,
1301         sizeof(int), XtOffset(AppDataPtr, firstNPS),
1302         XtRImmediate, (XtPointer) -1},
1303     { "secondNPS", "secondNPS", XtRInt,
1304         sizeof(int), XtOffset(AppDataPtr, secondNPS),
1305         XtRImmediate, (XtPointer) -1},
1306     { "serverMoves", "serverMoves", XtRString,
1307         sizeof(String), XtOffset(AppDataPtr, serverMovesName),
1308         XtRImmediate, (XtPointer) 0},
1309     { "serverPause", "serverPause", XtRInt,
1310         sizeof(int), XtOffset(AppDataPtr, serverPause),
1311         XtRImmediate, (XtPointer) 0},
1312     { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
1313         sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
1314         XtRImmediate, (XtPointer) False},
1315     { "userName", "userName", XtRString,
1316         sizeof(String), XtOffset(AppDataPtr, userName),
1317         XtRImmediate, (XtPointer) 0},
1318     { "egtFormats", "egtFormats", XtRString,
1319         sizeof(String), XtOffset(AppDataPtr, egtFormats),
1320         XtRImmediate, (XtPointer) 0},
1321     { "rewindIndex", "rewindIndex", XtRInt,
1322         sizeof(int), XtOffset(AppDataPtr, rewindIndex),
1323         XtRImmediate, (XtPointer) 0},
1324     { "sameColorGames", "sameColorGames", XtRInt,
1325         sizeof(int), XtOffset(AppDataPtr, sameColorGames),
1326         XtRImmediate, (XtPointer) 0},
1327     { "smpCores", "smpCores", XtRInt,
1328         sizeof(int), XtOffset(AppDataPtr, smpCores),
1329         XtRImmediate, (XtPointer) 1},
1330     { "niceEngines", "niceEngines", XtRInt,
1331         sizeof(int), XtOffset(AppDataPtr, niceEngines),
1332         XtRImmediate, (XtPointer) 0},
1333     { "nameOfDebugFile", "nameOfDebugFile", XtRString,
1334         sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
1335         XtRImmediate, (XtPointer) "xboard.debug"},
1336     { "engineDebugOutput", "engineDebugOutput", XtRInt,
1337         sizeof(int), XtOffset(AppDataPtr, engineComments),
1338         XtRImmediate, (XtPointer) 0},
1339     { "noGUI", "noGUI", XtRBoolean,
1340         sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
1341         XtRImmediate, (XtPointer) 0},
1342     { "firstOptions", "firstOptions", XtRString,
1343         sizeof(String), XtOffset(AppDataPtr, firstOptions),
1344         XtRImmediate, (XtPointer) "" },
1345     { "secondOptions", "secondOptions", XtRString,
1346         sizeof(String), XtOffset(AppDataPtr, secondOptions),
1347         XtRImmediate, (XtPointer) "" },
1348     { "firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XtRString,
1349         sizeof(String), XtOffset(AppDataPtr, fenOverride1),
1350         XtRImmediate, (XtPointer) 0 },
1351     { "secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XtRString,
1352         sizeof(String), XtOffset(AppDataPtr, fenOverride2),
1353         XtRImmediate, (XtPointer) 0 },
1354
1355     // [HGM] Winboard_x UCI options
1356     { "firstIsUCI", "firstIsUCI", XtRBoolean,
1357         sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
1358         XtRImmediate, (XtPointer) False},
1359     { "secondIsUCI", "secondIsUCI", XtRBoolean,
1360         sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
1361         XtRImmediate, (XtPointer) False},
1362     { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
1363         sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
1364         XtRImmediate, (XtPointer) True},
1365     { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
1366         sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
1367         XtRImmediate, (XtPointer) True},
1368     { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
1369         sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
1370         XtRImmediate, (XtPointer) False},
1371     { "defaultHashSize", "defaultHashSize", XtRInt,
1372         sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
1373         XtRImmediate, (XtPointer) 64},
1374     { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
1375         sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
1376         XtRImmediate, (XtPointer) 4},
1377     { "polyglotDir", "polyglotDir", XtRString,
1378         sizeof(String), XtOffset(AppDataPtr, polyglotDir),
1379         XtRImmediate, (XtPointer) "." },
1380     { "polyglotBook", "polyglotBook", XtRString,
1381         sizeof(String), XtOffset(AppDataPtr, polyglotBook),
1382         XtRImmediate, (XtPointer) "" },
1383     { "defaultPathEGTB", "defaultPathEGTB", XtRString,
1384         sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
1385         XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
1386     { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
1387         sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
1388         XtRImmediate, (XtPointer) 0},
1389     { "delayAfterQuit", "delayAfterQuit", XtRInt,
1390         sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
1391         XtRImmediate, (XtPointer) 0},
1392 };
1393
1394 XrmOptionDescRec shellOptions[] = {
1395     { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
1396     { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
1397     { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
1398     { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
1399     { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
1400     { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
1401     { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
1402     { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
1403     { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
1404     { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
1405     { "-initString", "initString", XrmoptionSepArg, NULL },
1406     { "-firstInitString", "initString", XrmoptionSepArg, NULL },
1407     { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
1408     { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
1409     { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
1410     { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
1411     { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
1412     { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
1413     { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
1414     { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
1415     { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
1416     { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
1417     { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
1418     { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
1419     { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
1420     { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
1421     { "-fh", "firstHost", XrmoptionSepArg, NULL },
1422     { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
1423     { "-sh", "secondHost", XrmoptionSepArg, NULL },
1424     { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
1425     { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
1426     { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
1427     { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
1428     { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
1429     { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
1430     { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
1431     { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
1432     { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
1433     { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
1434     { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
1435     { "-td", "timeDelay", XrmoptionSepArg, NULL },
1436     { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
1437     { "-tc", "timeControl", XrmoptionSepArg, NULL },
1438     { "-internetChessServerMode", "internetChessServerMode",
1439         XrmoptionSepArg, NULL },
1440     { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
1441     { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
1442     { "-internetChessServerHost", "internetChessServerHost",
1443         XrmoptionSepArg, NULL },
1444     { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
1445     { "-internetChessServerPort", "internetChessServerPort",
1446         XrmoptionSepArg, NULL },
1447     { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
1448     { "-internetChessServerCommPort", "internetChessServerCommPort",
1449         XrmoptionSepArg, NULL },
1450     { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
1451     { "-internetChessServerLogonScript", "internetChessServerLogonScript",
1452         XrmoptionSepArg, NULL },
1453     { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
1454     { "-internetChessServerHelper", "internetChessServerHelper",
1455         XrmoptionSepArg, NULL },
1456     { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
1457     { "-internetChessServerInputBox", "internetChessServerInputBox",
1458         XrmoptionSepArg, NULL },
1459     { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
1460     { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
1461     { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
1462     { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
1463     { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
1464     { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
1465     { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
1466     { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
1467     { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
1468     { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
1469     { "-gateway", "gateway", XrmoptionSepArg, NULL },
1470     { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
1471     { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
1472     { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
1473     { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
1474     { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
1475     { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
1476     { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
1477     { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
1478     { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
1479     { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
1480     { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
1481     { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
1482     { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
1483     { "-blind", "blindfold", XrmoptionNoArg, "True" },
1484     { "-xblind", "blindfold", XrmoptionNoArg, "False" },
1485     { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
1486     { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
1487     { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
1488     { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
1489     { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
1490     { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
1491     { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
1492     { "-mm", "matchMode", XrmoptionNoArg, "True" },
1493     { "-xmm", "matchMode", XrmoptionNoArg, "False" },
1494     { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
1495     { "-mg", "matchGames", XrmoptionSepArg, NULL },
1496     { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
1497     { "-mono", "monoMode", XrmoptionNoArg, "True" },
1498     { "-xmono", "monoMode", XrmoptionNoArg, "False" },
1499     { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
1500     { "-debug", "debugMode", XrmoptionNoArg, "True" },
1501     { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
1502     { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
1503     { "-clock", "clockMode", XrmoptionNoArg, "True" },
1504     { "-xclock", "clockMode", XrmoptionNoArg, "False" },
1505     { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
1506     { "-size", "boardSize", XrmoptionSepArg, NULL },
1507     { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
1508     { "-st", "searchTime", XrmoptionSepArg, NULL },
1509     { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
1510     { "-depth", "searchDepth", XrmoptionSepArg, NULL },
1511     { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
1512     { "-coords", "showCoords", XrmoptionNoArg, "True" },
1513     { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
1514 #if JAIL
1515     { "-showJail", "showJail", XrmoptionSepArg, NULL },
1516     { "-jail", "showJail", XrmoptionNoArg, "1" },
1517     { "-sidejail", "showJail", XrmoptionNoArg, "2" },
1518     { "-xjail", "showJail", XrmoptionNoArg, "0" },
1519 #endif
1520     { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
1521     { "-thinking", "showThinking", XrmoptionNoArg, "True" },
1522     { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
1523     { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
1524     { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
1525     { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
1526     { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
1527     { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
1528     { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
1529     { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
1530     { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
1531     { "-font", "font", XrmoptionSepArg, NULL },
1532     { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
1533     { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1534     { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1535     { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1536     { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1537     { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
1538     { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
1539     { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
1540     { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
1541     { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
1542     { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
1543     { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
1544     { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
1545     { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
1546     { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
1547     { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
1548     { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
1549     { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
1550     { "-moves", "getMoveList", XrmoptionNoArg, "True" },
1551     { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
1552 #if HIGHDRAG
1553     { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
1554     { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
1555     { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
1556 #endif
1557     { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
1558     { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
1559     { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
1560     { "-premove", "premove", XrmoptionSepArg, NULL },
1561     { "-pre", "premove", XrmoptionNoArg, "True" },
1562     { "-xpre", "premove", XrmoptionNoArg, "False" },
1563     { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
1564     { "-legal", "testLegality", XrmoptionNoArg, "True" },
1565     { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
1566     { "-flipView", "flipView", XrmoptionSepArg, NULL },
1567     { "-flip", "flipView", XrmoptionNoArg, "True" },
1568     { "-xflip", "flipView", XrmoptionNoArg, "False" },
1569     { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
1570     { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
1571         XrmoptionSepArg, NULL },
1572     { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
1573     { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
1574     { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
1575     { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
1576     { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
1577     { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
1578     { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
1579     { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
1580     { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
1581     { "-title", "titleInWindow", XrmoptionNoArg, "True" },
1582     { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
1583 #ifdef ZIPPY
1584     { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
1585     { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
1586     { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
1587     { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
1588     { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
1589     { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
1590     { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
1591     { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
1592     { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
1593     { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
1594     { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
1595     { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
1596     { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
1597     { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
1598     { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
1599     { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
1600     { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
1601     { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
1602     { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
1603     { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
1604     { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
1605     { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
1606     { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
1607     { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
1608     { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
1609     { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
1610     { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
1611     { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
1612     { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
1613     { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
1614     { "-zippyShortGame", "zippyShortGame", XrmoptionSepArg, NULL },
1615 #endif
1616     { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
1617     { "-flash", "flashCount", XrmoptionNoArg, "3" },
1618     { "-xflash", "flashCount", XrmoptionNoArg, "0" },
1619     { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
1620     { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
1621     { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
1622     { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
1623     { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
1624     { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
1625     { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
1626     { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
1627     { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
1628     { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1629     { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
1630     { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
1631     { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
1632     { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
1633     { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
1634     { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
1635     { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
1636     { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
1637     { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
1638     { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
1639     { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
1640     { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1641     { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
1642     { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
1643     { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
1644     { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
1645     { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
1646     { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
1647     { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
1648     { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
1649     { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
1650     { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
1651     { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
1652     { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
1653     { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
1654     { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
1655     { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
1656     { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
1657     { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
1658     { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
1659     { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
1660     { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
1661     { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
1662     { "-animate", "animateMoving", XrmoptionNoArg, "True" },
1663     { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
1664     { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
1665     { "-drag", "animateDragging", XrmoptionNoArg, "True" },
1666     { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
1667     { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
1668     { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
1669     { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
1670     { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
1671     { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
1672     { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
1673     { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
1674     { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
1675     { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
1676     { "-mode", "initialMode", XrmoptionSepArg, NULL },
1677     { "-variant", "variant", XrmoptionSepArg, NULL },
1678     { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
1679     { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
1680     { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
1681     { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
1682     { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
1683     { "-lowTimeWarningColor", "lowTimeWarningColor", XrmoptionSepArg, NULL },
1684     { "-lowTimeWarning", "lowTimeWarning", XrmoptionSepArg, NULL },
1685     /* [AS,HR] New features */
1686     { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
1687     { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
1688     { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
1689     { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
1690     { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
1691     { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
1692     { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
1693     { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
1694     { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
1695     { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
1696     { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
1697     { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
1698     { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1699     { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1700     { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1701     { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1702     { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
1703     { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
1704     { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
1705     { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
1706     { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
1707     { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
1708     { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
1709     { "-gameListTags", "gameListTags", XrmoptionSepArg, NULL },
1710     // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
1711
1712     /* [HGM,HR] User-selectable board size */
1713     { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
1714     { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
1715     { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
1716
1717     /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
1718     { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
1719     { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL },       // requires front-end changes to work
1720     { "-allWhite", "allWhite", XrmoptionSepArg, NULL },         // requires front-end changes to work
1721     { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
1722     { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
1723     { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
1724     { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
1725     { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
1726     { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
1727     { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
1728     { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
1729     { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1730     { "-userName", "userName", XrmoptionSepArg, NULL },
1731     { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
1732     { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
1733     { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
1734     { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
1735     { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
1736     { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
1737     { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
1738     { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
1739     { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
1740     { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
1741     { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
1742     { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
1743     { "-userName", "userName", XrmoptionSepArg, NULL },
1744     { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
1745     { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
1746     { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
1747     { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
1748     { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
1749     { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
1750     { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1751     { "-debugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1752     { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1753     { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
1754     { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
1755     { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
1756     { "-firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
1757     { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
1758 };
1759
1760
1761 XtActionsRec boardActions[] = {
1762     { "DrawPosition", DrawPositionProc },
1763     { "HandleUserMove", HandleUserMove },
1764     { "AnimateUserMove", AnimateUserMove },
1765     { "FileNameAction", FileNameAction },
1766     { "AskQuestionProc", AskQuestionProc },
1767     { "AskQuestionReplyAction", AskQuestionReplyAction },
1768     { "PieceMenuPopup", PieceMenuPopup },
1769     { "WhiteClock", WhiteClock },
1770     { "BlackClock", BlackClock },
1771     { "Iconify", Iconify },
1772     { "ResetProc", ResetProc },
1773     { "LoadGameProc", LoadGameProc },
1774     { "LoadNextGameProc", LoadNextGameProc },
1775     { "LoadPrevGameProc", LoadPrevGameProc },
1776     { "LoadSelectedProc", LoadSelectedProc },
1777     { "ReloadGameProc", ReloadGameProc },
1778     { "LoadPositionProc", LoadPositionProc },
1779     { "LoadNextPositionProc", LoadNextPositionProc },
1780     { "LoadPrevPositionProc", LoadPrevPositionProc },
1781     { "ReloadPositionProc", ReloadPositionProc },
1782     { "CopyPositionProc", CopyPositionProc },
1783     { "PastePositionProc", PastePositionProc },
1784     { "CopyGameProc", CopyGameProc },
1785     { "PasteGameProc", PasteGameProc },
1786     { "SaveGameProc", SaveGameProc },
1787     { "SavePositionProc", SavePositionProc },
1788     { "MailMoveProc", MailMoveProc },
1789     { "ReloadCmailMsgProc", ReloadCmailMsgProc },
1790     { "QuitProc", QuitProc },
1791     { "MachineWhiteProc", MachineWhiteProc },
1792     { "MachineBlackProc", MachineBlackProc },
1793     { "AnalysisModeProc", AnalyzeModeProc },
1794     { "AnalyzeFileProc", AnalyzeFileProc },
1795     { "TwoMachinesProc", TwoMachinesProc },
1796     { "IcsClientProc", IcsClientProc },
1797     { "EditGameProc", EditGameProc },
1798     { "EditPositionProc", EditPositionProc },
1799     { "TrainingProc", EditPositionProc },
1800     { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
1801     { "ShowGameListProc", ShowGameListProc },
1802     { "ShowMoveListProc", HistoryShowProc},
1803     { "EditTagsProc", EditCommentProc },
1804     { "EditCommentProc", EditCommentProc },
1805     { "IcsAlarmProc", IcsAlarmProc },
1806     { "IcsInputBoxProc", IcsInputBoxProc },
1807     { "PauseProc", PauseProc },
1808     { "AcceptProc", AcceptProc },
1809     { "DeclineProc", DeclineProc },
1810     { "RematchProc", RematchProc },
1811     { "CallFlagProc", CallFlagProc },
1812     { "DrawProc", DrawProc },
1813     { "AdjournProc", AdjournProc },
1814     { "AbortProc", AbortProc },
1815     { "ResignProc", ResignProc },
1816     { "AdjuWhiteProc", AdjuWhiteProc },
1817     { "AdjuBlackProc", AdjuBlackProc },
1818     { "AdjuDrawProc", AdjuDrawProc },
1819     { "EnterKeyProc", EnterKeyProc },
1820     { "StopObservingProc", StopObservingProc },
1821     { "StopExaminingProc", StopExaminingProc },
1822     { "BackwardProc", BackwardProc },
1823     { "ForwardProc", ForwardProc },
1824     { "ToStartProc", ToStartProc },
1825     { "ToEndProc", ToEndProc },
1826     { "RevertProc", RevertProc },
1827     { "TruncateGameProc", TruncateGameProc },
1828     { "MoveNowProc", MoveNowProc },
1829     { "RetractMoveProc", RetractMoveProc },
1830     { "AlwaysQueenProc", AlwaysQueenProc },
1831     { "AnimateDraggingProc", AnimateDraggingProc },
1832     { "AnimateMovingProc", AnimateMovingProc },
1833     { "AutoflagProc", AutoflagProc },
1834     { "AutoflipProc", AutoflipProc },
1835     { "AutobsProc", AutobsProc },
1836     { "AutoraiseProc", AutoraiseProc },
1837     { "AutosaveProc", AutosaveProc },
1838     { "BlindfoldProc", BlindfoldProc },
1839     { "FlashMovesProc", FlashMovesProc },
1840     { "FlipViewProc", FlipViewProc },
1841     { "GetMoveListProc", GetMoveListProc },
1842 #if HIGHDRAG
1843     { "HighlightDraggingProc", HighlightDraggingProc },
1844 #endif
1845     { "HighlightLastMoveProc", HighlightLastMoveProc },
1846     { "IcsAlarmProc", IcsAlarmProc },
1847     { "MoveSoundProc", MoveSoundProc },
1848     { "OldSaveStyleProc", OldSaveStyleProc },
1849     { "PeriodicUpdatesProc", PeriodicUpdatesProc },
1850     { "PonderNextMoveProc", PonderNextMoveProc },
1851     { "PopupExitMessageProc", PopupExitMessageProc },
1852     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
1853     { "PremoveProc", PremoveProc },
1854     { "QuietPlayProc", QuietPlayProc },
1855     { "ShowCoordsProc", ShowCoordsProc },
1856     { "ShowThinkingProc", ShowThinkingProc },
1857     { "HideThinkingProc", HideThinkingProc },
1858     { "TestLegalityProc", TestLegalityProc },
1859     { "InfoProc", InfoProc },
1860     { "ManProc", ManProc },
1861     { "HintProc", HintProc },
1862     { "BookProc", BookProc },
1863     { "AboutGameProc", AboutGameProc },
1864     { "AboutProc", AboutProc },
1865     { "DebugProc", DebugProc },
1866     { "NothingProc", NothingProc },
1867     { "CommentPopDown", (XtActionProc) CommentPopDown },
1868     { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
1869     { "TagsPopDown", (XtActionProc) TagsPopDown },
1870     { "ErrorPopDown", (XtActionProc) ErrorPopDown },
1871     { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
1872     { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
1873     { "FileNamePopDown", (XtActionProc) FileNamePopDown },
1874     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
1875     { "GameListPopDown", (XtActionProc) GameListPopDown },
1876     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
1877     { "HistoryPopDown", (XtActionProc) HistoryPopDown },
1878     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
1879     { "ShufflePopDown", (XtActionProc) ShufflePopDown },
1880     { "EnginePopDown", (XtActionProc) EnginePopDown },
1881     { "UciPopDown", (XtActionProc) UciPopDown },
1882     { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
1883     { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
1884     { "SettingsPopDown", (XtActionProc) SettingsPopDown },
1885 };
1886
1887 char globalTranslations[] =
1888   ":<Key>R: ResignProc() \n \
1889    :<Key>r: ResetProc() \n \
1890    :<Key>g: LoadGameProc() \n \
1891    :<Key>N: LoadNextGameProc() \n \
1892    :<Key>P: LoadPrevGameProc() \n \
1893    :<Key>Q: QuitProc() \n \
1894    :<Key>F: ToEndProc() \n \
1895    :<Key>f: ForwardProc() \n \
1896    :<Key>B: ToStartProc() \n \
1897    :<Key>b: BackwardProc() \n \
1898    :<Key>p: PauseProc() \n \
1899    :<Key>d: DrawProc() \n \
1900    :<Key>t: CallFlagProc() \n \
1901    :<Key>i: Iconify() \n \
1902    :<Key>c: Iconify() \n \
1903    :<Key>v: FlipViewProc() \n \
1904    <KeyDown>Control_L: BackwardProc() \n \
1905    <KeyUp>Control_L: ForwardProc() \n \
1906    <KeyDown>Control_R: BackwardProc() \n \
1907    <KeyUp>Control_R: ForwardProc() \n \
1908    Shift<Key>1: AskQuestionProc(\"Direct command\",\
1909                                 \"Send to chess program:\",,1) \n \
1910    Shift<Key>2: AskQuestionProc(\"Direct command\",\
1911                                 \"Send to second chess program:\",,2) \n";
1912
1913 char boardTranslations[] =
1914    "<Btn1Down>: HandleUserMove() \n \
1915    <Btn1Up>: HandleUserMove() \n \
1916    <Btn1Motion>: AnimateUserMove() \n \
1917    Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
1918                  PieceMenuPopup(menuB) \n \
1919    Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
1920                  PieceMenuPopup(menuW) \n \
1921    Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
1922                  PieceMenuPopup(menuW) \n \
1923    Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
1924                  PieceMenuPopup(menuB) \n";
1925
1926 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
1927 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
1928
1929 char ICSInputTranslations[] =
1930     "<Key>Return: EnterKeyProc() \n";
1931
1932 String xboardResources[] = {
1933     "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
1934     "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
1935     "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
1936     NULL
1937   };
1938
1939
1940 /* Max possible square size */
1941 #define MAXSQSIZE 256
1942
1943 static int xpm_avail[MAXSQSIZE];
1944
1945 #ifdef HAVE_DIR_STRUCT
1946
1947 /* Extract piece size from filename */
1948 static int
1949 xpm_getsize(name, len, ext)
1950      char *name;
1951      int len;
1952      char *ext;
1953 {
1954     char *p, *d;
1955     char buf[10];
1956
1957     if (len < 4)
1958       return 0;
1959
1960     if ((p=strchr(name, '.')) == NULL ||
1961         StrCaseCmp(p+1, ext) != 0)
1962       return 0;
1963
1964     p = name + 3;
1965     d = buf;
1966
1967     while (*p && isdigit(*p))
1968       *(d++) = *(p++);
1969
1970     *d = 0;
1971     return atoi(buf);
1972 }
1973
1974 /* Setup xpm_avail */
1975 static int
1976 xpm_getavail(dirname, ext)
1977      char *dirname;
1978      char *ext;
1979 {
1980     DIR *dir;
1981     struct dirent *ent;
1982     int  i;
1983
1984     for (i=0; i<MAXSQSIZE; ++i)
1985       xpm_avail[i] = 0;
1986
1987     if (appData.debugMode)
1988       fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
1989
1990     dir = opendir(dirname);
1991     if (!dir)
1992       {
1993           fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
1994                   programName, dirname);
1995           exit(1);
1996       }
1997
1998     while ((ent=readdir(dir)) != NULL) {
1999         i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
2000         if (i > 0 && i < MAXSQSIZE)
2001           xpm_avail[i] = 1;
2002     }
2003
2004     closedir(dir);
2005
2006     return 0;
2007 }
2008
2009 void
2010 xpm_print_avail(fp, ext)
2011      FILE *fp;
2012      char *ext;
2013 {
2014     int i;
2015
2016     fprintf(fp, _("Available `%s' sizes:\n"), ext);
2017     for (i=1; i<MAXSQSIZE; ++i) {
2018         if (xpm_avail[i])
2019           printf("%d\n", i);
2020     }
2021 }
2022
2023 /* Return XPM piecesize closest to size */
2024 int
2025 xpm_closest_to(dirname, size, ext)
2026      char *dirname;
2027      int size;
2028      char *ext;
2029 {
2030     int i;
2031     int sm_diff = MAXSQSIZE;
2032     int sm_index = 0;
2033     int diff;
2034
2035     xpm_getavail(dirname, ext);
2036
2037     if (appData.debugMode)
2038       xpm_print_avail(stderr, ext);
2039
2040     for (i=1; i<MAXSQSIZE; ++i) {
2041         if (xpm_avail[i]) {
2042             diff = size - i;
2043             diff = (diff<0) ? -diff : diff;
2044             if (diff < sm_diff) {
2045                 sm_diff = diff;
2046                 sm_index = i;
2047             }
2048         }
2049     }
2050
2051     if (!sm_index) {
2052         fprintf(stderr, _("Error: No `%s' files!\n"), ext);
2053         exit(1);
2054     }
2055
2056     return sm_index;
2057 }
2058 #else   /* !HAVE_DIR_STRUCT */
2059 /* If we are on a system without a DIR struct, we can't
2060    read the directory, so we can't collect a list of
2061    filenames, etc., so we can't do any size-fitting. */
2062 int
2063 xpm_closest_to(dirname, size, ext)
2064      char *dirname;
2065      int size;
2066      char *ext;
2067 {
2068     fprintf(stderr, _("\
2069 Warning: No DIR structure found on this system --\n\
2070          Unable to autosize for XPM/XIM pieces.\n\
2071    Please report this error to frankm@hiwaay.net.\n\
2072    Include system type & operating system in message.\n"));
2073     return size;
2074 }
2075 #endif /* HAVE_DIR_STRUCT */
2076
2077 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
2078                              "magenta", "cyan", "white" };
2079 typedef struct {
2080     int attr, bg, fg;
2081 } TextColors;
2082 TextColors textColors[(int)NColorClasses];
2083
2084 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
2085 static int
2086 parse_color(str, which)
2087      char *str;
2088      int which;
2089 {
2090     char *p, buf[100], *d;
2091     int i;
2092
2093     if (strlen(str) > 99)       /* watch bounds on buf */
2094       return -1;
2095
2096     p = str;
2097     d = buf;
2098     for (i=0; i<which; ++i) {
2099         p = strchr(p, ',');
2100         if (!p)
2101           return -1;
2102         ++p;
2103     }
2104
2105     /* Could be looking at something like:
2106        black, , 1
2107        .. in which case we want to stop on a comma also */
2108     while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
2109       ++p;
2110
2111     if (*p == ',') {
2112         return -1;              /* Use default for empty field */
2113     }
2114
2115     if (which == 2 || isdigit(*p))
2116       return atoi(p);
2117
2118     while (*p && isalpha(*p))
2119       *(d++) = *(p++);
2120
2121     *d = 0;
2122
2123     for (i=0; i<8; ++i) {
2124         if (!StrCaseCmp(buf, cnames[i]))
2125           return which? (i+40) : (i+30);
2126     }
2127     if (!StrCaseCmp(buf, "default")) return -1;
2128
2129     fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
2130     return -2;
2131 }
2132
2133 static int
2134 parse_cpair(cc, str)
2135      ColorClass cc;
2136      char *str;
2137 {
2138     if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
2139         fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
2140                 programName, str);
2141         return -1;
2142     }
2143
2144     /* bg and attr are optional */
2145     textColors[(int)cc].bg = parse_color(str, 1);
2146     if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
2147         textColors[(int)cc].attr = 0;
2148     }
2149     return 0;
2150 }
2151
2152
2153 /* Arrange to catch delete-window events */
2154 Atom wm_delete_window;
2155 void
2156 CatchDeleteWindow(Widget w, String procname)
2157 {
2158   char buf[MSG_SIZ];
2159   XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
2160   snprintf(buf, sizeof(buf), "<Message>WM_PROTOCOLS: %s() \n", procname);
2161   XtAugmentTranslations(w, XtParseTranslationTable(buf));
2162 }
2163
2164 void
2165 BoardToTop()
2166 {
2167   Arg args[16];
2168   XtSetArg(args[0], XtNiconic, False);
2169   XtSetValues(shellWidget, args, 1);
2170
2171   XtPopup(shellWidget, XtGrabNone); /* Raise if lowered  */
2172 }
2173
2174 #ifdef IDSIZES
2175   // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
2176 #else
2177 #define BoardSize int
2178 void InitDrawingSizes(BoardSize boardSize, int flags)
2179 {   // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
2180     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2181     Arg args[16];
2182     XtGeometryResult gres;
2183     int i;
2184
2185     if(!formWidget) return;
2186
2187     /*
2188      * Enable shell resizing.
2189      */
2190     shellArgs[0].value = (XtArgVal) &w;
2191     shellArgs[1].value = (XtArgVal) &h;
2192     XtGetValues(shellWidget, shellArgs, 2);
2193
2194     shellArgs[4].value = 2*w; shellArgs[2].value = 10;
2195     shellArgs[5].value = 2*h; shellArgs[3].value = 10;
2196     XtSetValues(shellWidget, &shellArgs[2], 4);
2197
2198     XtSetArg(args[0], XtNdefaultDistance, &sep);
2199     XtGetValues(formWidget, args, 1);
2200
2201     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2202     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2203     CreateGrid();
2204
2205     XtSetArg(args[0], XtNwidth, boardWidth);
2206     XtSetArg(args[1], XtNheight, boardHeight);
2207     XtSetValues(boardWidget, args, 2);
2208
2209     timerWidth = (boardWidth - sep) / 2;
2210     XtSetArg(args[0], XtNwidth, timerWidth);
2211     XtSetValues(whiteTimerWidget, args, 1);
2212     XtSetValues(blackTimerWidget, args, 1);
2213
2214     XawFormDoLayout(formWidget, False);
2215
2216     if (appData.titleInWindow) {
2217         i = 0;
2218         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2219         XtSetArg(args[i], XtNheight, &h);  i++;
2220         XtGetValues(titleWidget, args, i);
2221         if (smallLayout) {
2222             w = boardWidth - 2*bor;
2223         } else {
2224             XtSetArg(args[0], XtNwidth, &w);
2225             XtGetValues(menuBarWidget, args, 1);
2226             w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
2227         }
2228
2229         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2230         if (gres != XtGeometryYes && appData.debugMode) {
2231             fprintf(stderr,
2232                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2233                     programName, gres, w, h, wr, hr);
2234         }
2235     }
2236
2237     XawFormDoLayout(formWidget, True);
2238
2239     /*
2240      * Inhibit shell resizing.
2241      */
2242     shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
2243     shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
2244     shellArgs[4].value = shellArgs[2].value = w;
2245     shellArgs[5].value = shellArgs[3].value = h;
2246     XtSetValues(shellWidget, &shellArgs[0], 6);
2247 }
2248 #endif
2249
2250 int
2251 main(argc, argv)
2252      int argc;
2253      char **argv;
2254 {
2255     int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
2256     XSetWindowAttributes window_attributes;
2257     Arg args[16];
2258     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2259     XrmValue vFrom, vTo;
2260     XtGeometryResult gres;
2261     char *p;
2262     XrmDatabase xdb;
2263     int forceMono = False;
2264 #define INDIRECTION
2265 #ifdef INDIRECTION
2266     // [HGM] before anything else, expand any indirection files amongst options
2267     char *argvCopy[1000]; // 1000 seems enough
2268     char newArgs[10000];  // holds actual characters
2269     int k = 0;
2270
2271     srandom(time(0)); // [HGM] book: make random truly random
2272
2273     j = 0;
2274     for(i=0; i<argc; i++) {
2275         if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2276 //fprintf(stderr, "arg %s\n", argv[i]);
2277         if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
2278             char c;
2279             FILE *f = fopen(argv[i]+1, "rb");
2280             if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
2281             argvCopy[j++] = newArgs + k; // get ready for first argument from file
2282             while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
2283                 if(c == '\n') {
2284                     if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2285                     newArgs[k++] = 0;  // terminate current arg
2286                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2287                     argvCopy[j++] = newArgs + k; // get ready for next
2288                 } else {
2289                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2290                     newArgs[k++] = c;
2291                 }
2292             }
2293             newArgs[k] = 0;
2294             j--;
2295             fclose(f);
2296         }
2297     }
2298     argvCopy[j] = NULL;
2299     argv = argvCopy;
2300     argc = j;
2301 #if 0
2302     if(appData.debugMode,1) { // OK, appData is not initialized here yet...
2303         for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
2304     }
2305 #endif
2306 #endif
2307
2308
2309     setbuf(stdout, NULL);
2310     setbuf(stderr, NULL);
2311     debugFP = stderr;
2312
2313     programName = strrchr(argv[0], '/');
2314     if (programName == NULL)
2315       programName = argv[0];
2316     else
2317       programName++;
2318
2319 #ifdef ENABLE_NLS
2320     XtSetLanguageProc(NULL, NULL, NULL);
2321     bindtextdomain(PRODUCT, LOCALEDIR);
2322     textdomain(PRODUCT);
2323 #endif
2324
2325     shellWidget =
2326       XtAppInitialize(&appContext, "XBoard", shellOptions,
2327                       XtNumber(shellOptions),
2328                       &argc, argv, xboardResources, NULL, 0);
2329     if (argc > 1) {
2330         fprintf(stderr, _("%s: unrecognized argument %s\n"),
2331                 programName, argv[1]);
2332         exit(2);
2333     }
2334
2335     if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
2336         chessDir = ".";
2337     } else {
2338         if (chdir(chessDir) != 0) {
2339             fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
2340             perror(chessDir);
2341             exit(1);
2342         }
2343     }
2344
2345     p = getenv("HOME");
2346     if (p == NULL) p = "/tmp";
2347     i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
2348     gameCopyFilename = (char*) malloc(i);
2349     gamePasteFilename = (char*) malloc(i);
2350     snprintf(gameCopyFilename,i, "%s/.xboard%05uc.pgn", p, getpid());
2351     snprintf(gamePasteFilename,i, "%s/.xboard%05up.pgn", p, getpid());
2352
2353     XtGetApplicationResources(shellWidget, (XtPointer) &appData,
2354                               clientResources, XtNumber(clientResources),
2355                               NULL, 0);
2356
2357     if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
2358         /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
2359         if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
2360            printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
2361            exit(errno);
2362         }
2363         setbuf(debugFP, NULL);
2364     }
2365
2366     /* [HGM,HR] make sure board size is acceptable */
2367     if(appData.NrFiles > BOARD_SIZE ||
2368        appData.NrRanks > BOARD_SIZE   )
2369          DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
2370
2371 #if !HIGHDRAG
2372     /* This feature does not work; animation needs a rewrite */
2373     appData.highlightDragging = FALSE;
2374 #endif
2375     InitBackEnd1();
2376
2377     xDisplay = XtDisplay(shellWidget);
2378     xScreen = DefaultScreen(xDisplay);
2379     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
2380
2381         gameInfo.variant = StringToVariant(appData.variant);
2382         InitPosition(FALSE);
2383 #if 0
2384     /*
2385      * Determine boardSize
2386      */
2387     gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
2388
2389 //#ifndef IDSIZE
2390     // [HGM] as long as we have not created the possibility to change size while running, start with requested size
2391     gameInfo.boardWidth    = appData.NrFiles > 0 ? appData.NrFiles : 8;
2392     gameInfo.boardHeight   = appData.NrRanks > 0 ? appData.NrRanks : 8;
2393     gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
2394 #endif
2395
2396
2397 #ifdef IDSIZE
2398     InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
2399 #else
2400     if (isdigit(appData.boardSize[0])) {
2401         i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
2402                    &lineGap, &clockFontPxlSize, &coordFontPxlSize,
2403                    &fontPxlSize, &smallLayout, &tinyLayout);
2404         if (i == 0) {
2405             fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
2406                     programName, appData.boardSize);
2407             exit(2);
2408         }
2409         if (i < 7) {
2410             /* Find some defaults; use the nearest known size */
2411             SizeDefaults *szd, *nearest;
2412             int distance = 99999;
2413             nearest = szd = sizeDefaults;
2414             while (szd->name != NULL) {
2415                 if (abs(szd->squareSize - squareSize) < distance) {
2416                     nearest = szd;
2417                     distance = abs(szd->squareSize - squareSize);
2418                     if (distance == 0) break;
2419                 }
2420                 szd++;
2421             }
2422             if (i < 2) lineGap = nearest->lineGap;
2423             if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
2424             if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
2425             if (i < 5) fontPxlSize = nearest->fontPxlSize;
2426             if (i < 6) smallLayout = nearest->smallLayout;
2427             if (i < 7) tinyLayout = nearest->tinyLayout;
2428         }
2429     } else {
2430         SizeDefaults *szd = sizeDefaults;
2431         if (*appData.boardSize == NULLCHAR) {
2432             while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
2433                    DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
2434               szd++;
2435             }
2436             if (szd->name == NULL) szd--;
2437         } else {
2438             while (szd->name != NULL &&
2439                    StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
2440             if (szd->name == NULL) {
2441                 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
2442                         programName, appData.boardSize);
2443                 exit(2);
2444             }
2445         }
2446         squareSize = szd->squareSize;
2447         lineGap = szd->lineGap;
2448         clockFontPxlSize = szd->clockFontPxlSize;
2449         coordFontPxlSize = szd->coordFontPxlSize;
2450         fontPxlSize = szd->fontPxlSize;
2451         smallLayout = szd->smallLayout;
2452         tinyLayout = szd->tinyLayout;
2453     }
2454
2455     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
2456     if (strlen(appData.pixmapDirectory) > 0) {
2457         p = ExpandPathName(appData.pixmapDirectory);
2458         if (!p) {
2459             fprintf(stderr, _("Error expanding path name \"%s\"\n"),
2460                    appData.pixmapDirectory);
2461             exit(1);
2462         }
2463         if (appData.debugMode) {
2464           fprintf(stderr, _("\
2465 XBoard square size (hint): %d\n\
2466 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
2467         }
2468         squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
2469         if (appData.debugMode) {
2470             fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
2471         }
2472     }
2473
2474     /* [HR] height treated separately (hacked) */
2475     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2476     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2477     if (appData.showJail == 1) {
2478         /* Jail on top and bottom */
2479         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2480         XtSetArg(boardArgs[2], XtNheight,
2481                  boardHeight + 2*(lineGap + squareSize));
2482     } else if (appData.showJail == 2) {
2483         /* Jail on sides */
2484         XtSetArg(boardArgs[1], XtNwidth,
2485                  boardWidth + 2*(lineGap + squareSize));
2486         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2487     } else {
2488         /* No jail */
2489         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2490         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2491     }
2492
2493     /*
2494      * Determine what fonts to use.
2495      */
2496     appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
2497     clockFontID = XLoadFont(xDisplay, appData.clockFont);
2498     clockFontStruct = XQueryFont(xDisplay, clockFontID);
2499     appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
2500     coordFontID = XLoadFont(xDisplay, appData.coordFont);
2501     coordFontStruct = XQueryFont(xDisplay, coordFontID);
2502     appData.font = FindFont(appData.font, fontPxlSize);
2503     countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
2504     countFontStruct = XQueryFont(xDisplay, countFontID);
2505 //    appData.font = FindFont(appData.font, fontPxlSize);
2506
2507     xdb = XtDatabase(xDisplay);
2508     XrmPutStringResource(&xdb, "*font", appData.font);
2509
2510     /*
2511      * Detect if there are not enough colors available and adapt.
2512      */
2513     if (DefaultDepth(xDisplay, xScreen) <= 2) {
2514       appData.monoMode = True;
2515     }
2516
2517     if (!appData.monoMode) {
2518         vFrom.addr = (caddr_t) appData.lightSquareColor;
2519         vFrom.size = strlen(appData.lightSquareColor);
2520         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2521         if (vTo.addr == NULL) {
2522           appData.monoMode = True;
2523           forceMono = True;
2524         } else {
2525           lightSquareColor = *(Pixel *) vTo.addr;
2526         }
2527     }
2528     if (!appData.monoMode) {
2529         vFrom.addr = (caddr_t) appData.darkSquareColor;
2530         vFrom.size = strlen(appData.darkSquareColor);
2531         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2532         if (vTo.addr == NULL) {
2533           appData.monoMode = True;
2534           forceMono = True;
2535         } else {
2536           darkSquareColor = *(Pixel *) vTo.addr;
2537         }
2538     }
2539     if (!appData.monoMode) {
2540         vFrom.addr = (caddr_t) appData.whitePieceColor;
2541         vFrom.size = strlen(appData.whitePieceColor);
2542         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2543         if (vTo.addr == NULL) {
2544           appData.monoMode = True;
2545           forceMono = True;
2546         } else {
2547           whitePieceColor = *(Pixel *) vTo.addr;
2548         }
2549     }
2550     if (!appData.monoMode) {
2551         vFrom.addr = (caddr_t) appData.blackPieceColor;
2552         vFrom.size = strlen(appData.blackPieceColor);
2553         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2554         if (vTo.addr == NULL) {
2555           appData.monoMode = True;
2556           forceMono = True;
2557         } else {
2558           blackPieceColor = *(Pixel *) vTo.addr;
2559         }
2560     }
2561
2562     if (!appData.monoMode) {
2563         vFrom.addr = (caddr_t) appData.highlightSquareColor;
2564         vFrom.size = strlen(appData.highlightSquareColor);
2565         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2566         if (vTo.addr == NULL) {
2567           appData.monoMode = True;
2568           forceMono = True;
2569         } else {
2570           highlightSquareColor = *(Pixel *) vTo.addr;
2571         }
2572     }
2573
2574     if (!appData.monoMode) {
2575         vFrom.addr = (caddr_t) appData.premoveHighlightColor;
2576         vFrom.size = strlen(appData.premoveHighlightColor);
2577         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2578         if (vTo.addr == NULL) {
2579           appData.monoMode = True;
2580           forceMono = True;
2581         } else {
2582           premoveHighlightColor = *(Pixel *) vTo.addr;
2583         }
2584     }
2585
2586     if (forceMono) {
2587       fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
2588               programName);
2589     }
2590
2591     if (appData.lowTimeWarning && !appData.monoMode) {
2592       vFrom.addr = (caddr_t) appData.lowTimeWarningColor;
2593       vFrom.size = strlen(appData.lowTimeWarningColor);
2594       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2595       if (vTo.addr == NULL) 
2596                 appData.monoMode = True;
2597       else
2598                 lowTimeWarningColor = *(Pixel *) vTo.addr;
2599     }
2600
2601     if (appData.monoMode && appData.debugMode) {
2602         fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
2603                 (unsigned long) XWhitePixel(xDisplay, xScreen),
2604                 (unsigned long) XBlackPixel(xDisplay, xScreen));
2605     }
2606
2607     if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
2608         parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
2609         parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
2610         parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
2611         parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
2612         parse_cpair(ColorTell, appData.colorTell) < 0 ||
2613         parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
2614         parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
2615         parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
2616         parse_cpair(ColorNormal, appData.colorNormal) < 0)
2617       {
2618           if (appData.colorize) {
2619               fprintf(stderr,
2620                       _("%s: can't parse color names; disabling colorization\n"),
2621                       programName);
2622           }
2623           appData.colorize = FALSE;
2624       }
2625     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
2626     textColors[ColorNone].attr = 0;
2627
2628     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
2629
2630     /*
2631      * widget hierarchy
2632      */
2633     if (tinyLayout) {
2634         layoutName = "tinyLayout";
2635     } else if (smallLayout) {
2636         layoutName = "smallLayout";
2637     } else {
2638         layoutName = "normalLayout";
2639     }
2640     /* Outer layoutWidget is there only to provide a name for use in
2641        resources that depend on the layout style */
2642     layoutWidget =
2643       XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
2644                             layoutArgs, XtNumber(layoutArgs));
2645     formWidget =
2646       XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
2647                             formArgs, XtNumber(formArgs));
2648     XtSetArg(args[0], XtNdefaultDistance, &sep);
2649     XtGetValues(formWidget, args, 1);
2650
2651     j = 0;
2652     widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
2653     XtSetArg(args[0], XtNtop,    XtChainTop);
2654     XtSetArg(args[1], XtNbottom, XtChainTop);
2655     XtSetValues(menuBarWidget, args, 2);
2656
2657     widgetList[j++] = whiteTimerWidget =
2658       XtCreateWidget("whiteTime", labelWidgetClass,
2659                      formWidget, timerArgs, XtNumber(timerArgs));
2660     XtSetArg(args[0], XtNfont, clockFontStruct);
2661     XtSetArg(args[1], XtNtop,    XtChainTop);
2662     XtSetArg(args[2], XtNbottom, XtChainTop);
2663     XtSetValues(whiteTimerWidget, args, 3);
2664
2665     widgetList[j++] = blackTimerWidget =
2666       XtCreateWidget("blackTime", labelWidgetClass,
2667                      formWidget, timerArgs, XtNumber(timerArgs));
2668     XtSetArg(args[0], XtNfont, clockFontStruct);
2669     XtSetArg(args[1], XtNtop,    XtChainTop);
2670     XtSetArg(args[2], XtNbottom, XtChainTop);
2671     XtSetValues(blackTimerWidget, args, 3);
2672
2673     if (appData.titleInWindow) {
2674         widgetList[j++] = titleWidget =
2675           XtCreateWidget("title", labelWidgetClass, formWidget,
2676                          titleArgs, XtNumber(titleArgs));
2677         XtSetArg(args[0], XtNtop,    XtChainTop);
2678         XtSetArg(args[1], XtNbottom, XtChainTop);
2679         XtSetValues(titleWidget, args, 2);
2680     }
2681
2682     if (appData.showButtonBar) {
2683       widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
2684       XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge
2685       XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
2686       XtSetArg(args[2], XtNtop,    XtChainTop);
2687       XtSetArg(args[3], XtNbottom, XtChainTop);
2688       XtSetValues(buttonBarWidget, args, 4);
2689     }
2690
2691     widgetList[j++] = messageWidget =
2692       XtCreateWidget("message", labelWidgetClass, formWidget,
2693                      messageArgs, XtNumber(messageArgs));
2694     XtSetArg(args[0], XtNtop,    XtChainTop);
2695     XtSetArg(args[1], XtNbottom, XtChainTop);
2696     XtSetValues(messageWidget, args, 2);
2697
2698     widgetList[j++] = boardWidget =
2699       XtCreateWidget("board", widgetClass, formWidget, boardArgs,
2700                      XtNumber(boardArgs));
2701
2702     XtManageChildren(widgetList, j);
2703
2704     timerWidth = (boardWidth - sep) / 2;
2705     XtSetArg(args[0], XtNwidth, timerWidth);
2706     XtSetValues(whiteTimerWidget, args, 1);
2707     XtSetValues(blackTimerWidget, args, 1);
2708
2709     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
2710     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
2711     XtGetValues(whiteTimerWidget, args, 2);
2712
2713     if (appData.showButtonBar) {
2714       XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
2715       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
2716       XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
2717     }
2718
2719     /*
2720      * formWidget uses these constraints but they are stored
2721      * in the children.
2722      */
2723     i = 0;
2724     XtSetArg(args[i], XtNfromHoriz, 0); i++;
2725     XtSetValues(menuBarWidget, args, i);
2726     if (appData.titleInWindow) {
2727         if (smallLayout) {
2728             i = 0;
2729             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2730             XtSetValues(whiteTimerWidget, args, i);
2731             i = 0;
2732             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2733             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2734             XtSetValues(blackTimerWidget, args, i);
2735             i = 0;
2736             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2737             XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
2738             XtSetValues(titleWidget, args, i);
2739             i = 0;
2740             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2741             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2742             XtSetValues(messageWidget, args, i);
2743             if (appData.showButtonBar) {
2744               i = 0;
2745               XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2746               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2747               XtSetValues(buttonBarWidget, args, i);
2748             }
2749         } else {
2750             i = 0;
2751             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2752             XtSetValues(whiteTimerWidget, args, i);
2753             i = 0;
2754             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2755             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2756             XtSetValues(blackTimerWidget, args, i);
2757             i = 0;
2758             XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
2759             XtSetValues(titleWidget, args, i);
2760             i = 0;
2761             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2762             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2763             XtSetValues(messageWidget, args, i);
2764             if (appData.showButtonBar) {
2765               i = 0;
2766               XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2767               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2768               XtSetValues(buttonBarWidget, args, i);
2769             }
2770         }
2771     } else {
2772         i = 0;
2773         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2774         XtSetValues(whiteTimerWidget, args, i);
2775         i = 0;
2776         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2777         XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2778         XtSetValues(blackTimerWidget, args, i);
2779         i = 0;
2780         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2781         XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2782         XtSetValues(messageWidget, args, i);
2783         if (appData.showButtonBar) {
2784           i = 0;
2785           XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2786           XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2787           XtSetValues(buttonBarWidget, args, i);
2788         }
2789     }
2790     i = 0;
2791     XtSetArg(args[0], XtNfromVert, messageWidget);
2792     XtSetArg(args[1], XtNtop,    XtChainTop);
2793     XtSetArg(args[2], XtNbottom, XtChainBottom);
2794     XtSetArg(args[3], XtNleft,   XtChainLeft);
2795     XtSetArg(args[4], XtNright,  XtChainRight);
2796     XtSetValues(boardWidget, args, 5);
2797
2798     XtRealizeWidget(shellWidget);
2799
2800     /*
2801      * Correct the width of the message and title widgets.
2802      * It is not known why some systems need the extra fudge term.
2803      * The value "2" is probably larger than needed.
2804      */
2805     XawFormDoLayout(formWidget, False);
2806
2807 #define WIDTH_FUDGE 2
2808     i = 0;
2809     XtSetArg(args[i], XtNborderWidth, &bor);  i++;
2810     XtSetArg(args[i], XtNheight, &h);  i++;
2811     XtGetValues(messageWidget, args, i);
2812     if (appData.showButtonBar) {
2813       i = 0;
2814       XtSetArg(args[i], XtNwidth, &w);  i++;
2815       XtGetValues(buttonBarWidget, args, i);
2816       w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2817     } else {
2818       w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
2819     }
2820
2821     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2822     if (gres != XtGeometryYes && appData.debugMode) {
2823       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2824               programName, gres, w, h, wr, hr);
2825     }
2826
2827     /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
2828     /* The size used for the child widget in layout lags one resize behind
2829        its true size, so we resize a second time, 1 pixel smaller.  Yeech! */
2830     w--;
2831     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2832     if (gres != XtGeometryYes && appData.debugMode) {
2833       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2834               programName, gres, w, h, wr, hr);
2835     }
2836     /* !! end hack */
2837     XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing
2838     XtSetArg(args[1], XtNright, XtChainRight);
2839     XtSetValues(messageWidget, args, 2);
2840
2841     if (appData.titleInWindow) {
2842         i = 0;
2843         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2844         XtSetArg(args[i], XtNheight, &h);  i++;
2845         XtGetValues(titleWidget, args, i);
2846         if (smallLayout) {
2847             w = boardWidth - 2*bor;
2848         } else {
2849             XtSetArg(args[0], XtNwidth, &w);
2850             XtGetValues(menuBarWidget, args, 1);
2851             w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2852         }
2853
2854         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2855         if (gres != XtGeometryYes && appData.debugMode) {
2856             fprintf(stderr,
2857                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2858                     programName, gres, w, h, wr, hr);
2859         }
2860     }
2861     XawFormDoLayout(formWidget, True);
2862
2863     xBoardWindow = XtWindow(boardWidget);
2864
2865     // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
2866     //       not need to go into InitDrawingSizes().
2867 #endif
2868
2869     /*
2870      * Create X checkmark bitmap and initialize option menu checks.
2871      */
2872     ReadBitmap(&xMarkPixmap, "checkmark.bm",
2873                checkmark_bits, checkmark_width, checkmark_height);
2874     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
2875     if (appData.alwaysPromoteToQueen) {
2876         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
2877                     args, 1);
2878     }
2879     if (appData.animateDragging) {
2880         XtSetValues(XtNameToWidget(menuBarWidget,
2881                                    "menuOptions.Animate Dragging"),
2882                     args, 1);
2883     }
2884     if (appData.animate) {
2885         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
2886                     args, 1);
2887     }
2888     if (appData.autoComment) {
2889         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
2890                     args, 1);
2891     }
2892     if (appData.autoCallFlag) {
2893         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
2894                     args, 1);
2895     }
2896     if (appData.autoFlipView) {
2897         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
2898                     args, 1);
2899     }
2900     if (appData.autoObserve) {
2901         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
2902                     args, 1);
2903     }
2904     if (appData.autoRaiseBoard) {
2905         XtSetValues(XtNameToWidget(menuBarWidget,
2906                                    "menuOptions.Auto Raise Board"), args, 1);
2907     }
2908     if (appData.autoSaveGames) {
2909         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2910                     args, 1);
2911     }
2912     if (appData.saveGameFile[0] != NULLCHAR) {
2913         /* Can't turn this off from menu */
2914         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2915                     args, 1);
2916         XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
2917                        False);
2918
2919     }
2920     if (appData.blindfold) {
2921         XtSetValues(XtNameToWidget(menuBarWidget,
2922                                    "menuOptions.Blindfold"), args, 1);
2923     }
2924     if (appData.flashCount > 0) {
2925         XtSetValues(XtNameToWidget(menuBarWidget,
2926                                    "menuOptions.Flash Moves"),
2927                     args, 1);
2928     }
2929     if (appData.getMoveList) {
2930         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
2931                     args, 1);
2932     }
2933 #if HIGHDRAG
2934     if (appData.highlightDragging) {
2935         XtSetValues(XtNameToWidget(menuBarWidget,
2936                                    "menuOptions.Highlight Dragging"),
2937                     args, 1);
2938     }
2939 #endif
2940     if (appData.highlightLastMove) {
2941         XtSetValues(XtNameToWidget(menuBarWidget,
2942                                    "menuOptions.Highlight Last Move"),
2943                     args, 1);
2944     }
2945     if (appData.icsAlarm) {
2946         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
2947                     args, 1);
2948     }
2949     if (appData.ringBellAfterMoves) {
2950         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
2951                     args, 1);
2952     }
2953     if (appData.oldSaveStyle) {
2954         XtSetValues(XtNameToWidget(menuBarWidget,
2955                                    "menuOptions.Old Save Style"), args, 1);
2956     }
2957     if (appData.periodicUpdates) {
2958         XtSetValues(XtNameToWidget(menuBarWidget,
2959                                    "menuOptions.Periodic Updates"), args, 1);
2960     }
2961     if (appData.ponderNextMove) {
2962         XtSetValues(XtNameToWidget(menuBarWidget,
2963                                    "menuOptions.Ponder Next Move"), args, 1);
2964     }
2965     if (appData.popupExitMessage) {
2966         XtSetValues(XtNameToWidget(menuBarWidget,
2967                                    "menuOptions.Popup Exit Message"), args, 1);
2968     }
2969     if (appData.popupMoveErrors) {
2970         XtSetValues(XtNameToWidget(menuBarWidget,
2971                                    "menuOptions.Popup Move Errors"), args, 1);
2972     }
2973     if (appData.premove) {
2974         XtSetValues(XtNameToWidget(menuBarWidget,
2975                                    "menuOptions.Premove"), args, 1);
2976     }
2977     if (appData.quietPlay) {
2978         XtSetValues(XtNameToWidget(menuBarWidget,
2979                                    "menuOptions.Quiet Play"), args, 1);
2980     }
2981     if (appData.showCoords) {
2982         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
2983                     args, 1);
2984     }
2985     if (appData.hideThinkingFromHuman) {
2986         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
2987                     args, 1);
2988     }
2989     if (appData.testLegality) {
2990         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
2991                     args, 1);
2992     }
2993
2994     /*
2995      * Create an icon.
2996      */
2997     ReadBitmap(&wIconPixmap, "icon_white.bm",
2998                icon_white_bits, icon_white_width, icon_white_height);
2999     ReadBitmap(&bIconPixmap, "icon_black.bm",
3000                icon_black_bits, icon_black_width, icon_black_height);
3001     iconPixmap = wIconPixmap;
3002     i = 0;
3003     XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
3004     XtSetValues(shellWidget, args, i);
3005
3006     /*
3007      * Create a cursor for the board widget.
3008      */
3009     window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
3010     XChangeWindowAttributes(xDisplay, xBoardWindow,
3011                             CWCursor, &window_attributes);
3012
3013     /*
3014      * Inhibit shell resizing.
3015      */
3016     shellArgs[0].value = (XtArgVal) &w;
3017     shellArgs[1].value = (XtArgVal) &h;
3018     XtGetValues(shellWidget, shellArgs, 2);
3019     shellArgs[4].value = shellArgs[2].value = w;
3020     shellArgs[5].value = shellArgs[3].value = h;
3021     XtSetValues(shellWidget, &shellArgs[2], 4);
3022     marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
3023     marginH =  h - boardHeight;
3024
3025     CatchDeleteWindow(shellWidget, "QuitProc");
3026
3027     CreateGCs();
3028     CreateGrid();
3029 #if HAVE_LIBXPM
3030     if (appData.bitmapDirectory[0] != NULLCHAR) {
3031       CreatePieces();
3032     } else {
3033       CreateXPMPieces();
3034     }
3035 #else
3036     CreateXIMPieces();
3037     /* Create regular pieces */
3038     if (!useImages) CreatePieces();
3039 #endif
3040
3041     CreatePieceMenus();
3042
3043     if (appData.animate || appData.animateDragging)
3044       CreateAnimVars();
3045
3046     XtAugmentTranslations(formWidget,
3047                           XtParseTranslationTable(globalTranslations));
3048     XtAugmentTranslations(boardWidget,
3049                           XtParseTranslationTable(boardTranslations));
3050     XtAugmentTranslations(whiteTimerWidget,
3051                           XtParseTranslationTable(whiteTranslations));
3052     XtAugmentTranslations(blackTimerWidget,
3053                           XtParseTranslationTable(blackTranslations));
3054
3055     /* Why is the following needed on some versions of X instead
3056      * of a translation? */
3057     XtAddEventHandler(boardWidget, ExposureMask, False,
3058                       (XtEventHandler) EventProc, NULL);
3059     /* end why */
3060
3061     InitBackEnd2();
3062
3063     if (errorExitStatus == -1) {
3064         if (appData.icsActive) {
3065             /* We now wait until we see "login:" from the ICS before
3066                sending the logon script (problems with timestamp otherwise) */
3067             /*ICSInitScript();*/
3068             if (appData.icsInputBox) ICSInputBoxPopUp();
3069         }
3070
3071         signal(SIGINT, IntSigHandler);
3072         signal(SIGTERM, IntSigHandler);
3073         if (*appData.cmailGameName != NULLCHAR) {
3074             signal(SIGUSR1, CmailSigHandler);
3075         }
3076     }
3077         InitPosition(TRUE);
3078
3079     XtAppMainLoop(appContext);
3080     if (appData.debugMode) fclose(debugFP); // [DM] debug
3081     return 0;
3082 }
3083
3084 void
3085 ShutDownFrontEnd()
3086 {
3087     if (appData.icsActive && oldICSInteractionTitle != NULL) {
3088         DisplayIcsInteractionTitle(oldICSInteractionTitle);
3089     }
3090     unlink(gameCopyFilename);
3091     unlink(gamePasteFilename);
3092 }
3093
3094 RETSIGTYPE
3095 IntSigHandler(sig)
3096      int sig;
3097 {
3098     ExitEvent(sig);
3099 }
3100
3101 RETSIGTYPE
3102 CmailSigHandler(sig)
3103      int sig;
3104 {
3105     int dummy = 0;
3106     int error;
3107
3108     signal(SIGUSR1, SIG_IGN);   /* suspend handler     */
3109
3110     /* Activate call-back function CmailSigHandlerCallBack()             */
3111     OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
3112
3113     signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
3114 }
3115
3116 void
3117 CmailSigHandlerCallBack(isr, closure, message, count, error)
3118      InputSourceRef isr;
3119      VOIDSTAR closure;
3120      char *message;
3121      int count;
3122      int error;
3123 {
3124     BoardToTop();
3125     ReloadCmailMsgEvent(TRUE);  /* Reload cmail msg  */
3126 }
3127 /**** end signal code ****/
3128
3129
3130 void
3131 ICSInitScript()
3132 {
3133     FILE *f;
3134     char buf[MSG_SIZ];
3135     char *p;
3136
3137     f = fopen(appData.icsLogon, "r");
3138     if (f == NULL) {
3139         p = getenv("HOME");
3140         if (p != NULL) {
3141             strcpy(buf, p);
3142             strcat(buf, "/");
3143             strcat(buf, appData.icsLogon);
3144             f = fopen(buf, "r");
3145         }
3146     }
3147     if (f != NULL)
3148       ProcessICSInitScript(f);
3149 }
3150
3151 void
3152 ResetFrontEnd()
3153 {
3154     CommentPopDown();
3155     EditCommentPopDown();
3156     TagsPopDown();
3157     return;
3158 }
3159
3160 typedef struct {
3161     char *name;
3162     Boolean value;
3163 } Enables;
3164
3165 void
3166 SetMenuEnables(enab)
3167      Enables *enab;
3168 {
3169   Widget w;
3170   if (!menuBarWidget) return;
3171   while (enab->name != NULL) {
3172     w = XtNameToWidget(menuBarWidget, enab->name);
3173     if (w == NULL) {
3174       DisplayError(enab->name, 0);
3175     } else {
3176       XtSetSensitive(w, enab->value);
3177     }
3178     enab++;
3179   }
3180 }
3181
3182 Enables icsEnables[] = {
3183     { "menuFile.Mail Move", False },
3184     { "menuFile.Reload CMail Message", False },
3185     { "menuMode.Machine Black", False },
3186     { "menuMode.Machine White", False },
3187     { "menuMode.Analysis Mode", False },
3188     { "menuMode.Analyze File", False },
3189     { "menuMode.Two Machines", False },
3190 #ifndef ZIPPY
3191     { "menuHelp.Hint", False },
3192     { "menuHelp.Book", False },
3193     { "menuStep.Move Now", False },
3194     { "menuOptions.Periodic Updates", False },
3195     { "menuOptions.Hide Thinking", False },
3196     { "menuOptions.Ponder Next Move", False },
3197 #endif
3198     { NULL, False }
3199 };
3200
3201 Enables ncpEnables[] = {
3202     { "menuFile.Mail Move", False },
3203     { "menuFile.Reload CMail Message", False },
3204     { "menuMode.Machine White", False },
3205     { "menuMode.Machine Black", False },
3206     { "menuMode.Analysis Mode", False },
3207     { "menuMode.Analyze File", False },
3208     { "menuMode.Two Machines", False },
3209     { "menuMode.ICS Client", False },
3210     { "menuMode.ICS Input Box", False },
3211     { "Action", False },
3212     { "menuStep.Revert", False },
3213     { "menuStep.Move Now", False },
3214     { "menuStep.Retract Move", False },
3215     { "menuOptions.Auto Comment", False },
3216     { "menuOptions.Auto Flag", False },
3217     { "menuOptions.Auto Flip View", False },
3218     { "menuOptions.Auto Observe", False },
3219     { "menuOptions.Auto Raise Board", False },
3220     { "menuOptions.Get Move List", False },
3221     { "menuOptions.ICS Alarm", False },
3222     { "menuOptions.Move Sound", False },
3223     { "menuOptions.Quiet Play", False },
3224     { "menuOptions.Hide Thinking", False },
3225     { "menuOptions.Periodic Updates", False },
3226     { "menuOptions.Ponder Next Move", False },
3227     { "menuHelp.Hint", False },
3228     { "menuHelp.Book", False },
3229     { NULL, False }
3230 };
3231
3232 Enables gnuEnables[] = {
3233     { "menuMode.ICS Client", False },
3234     { "menuMode.ICS Input Box", False },
3235     { "menuAction.Accept", False },
3236     { "menuAction.Decline", False },
3237     { "menuAction.Rematch", False },
3238     { "menuAction.Adjourn", False },
3239     { "menuAction.Stop Examining", False },
3240     { "menuAction.Stop Observing", False },
3241     { "menuStep.Revert", False },
3242     { "menuOptions.Auto Comment", False },
3243     { "menuOptions.Auto Observe", False },
3244     { "menuOptions.Auto Raise Board", False },
3245     { "menuOptions.Get Move List", False },
3246     { "menuOptions.Premove", False },
3247     { "menuOptions.Quiet Play", False },
3248
3249     /* The next two options rely on SetCmailMode being called *after*    */
3250     /* SetGNUMode so that when GNU is being used to give hints these     */
3251     /* menu options are still available                                  */
3252
3253     { "menuFile.Mail Move", False },
3254     { "menuFile.Reload CMail Message", False },
3255     { NULL, False }
3256 };
3257
3258 Enables cmailEnables[] = {
3259     { "Action", True },
3260     { "menuAction.Call Flag", False },
3261     { "menuAction.Draw", True },
3262     { "menuAction.Adjourn", False },
3263     { "menuAction.Abort", False },
3264     { "menuAction.Stop Observing", False },
3265     { "menuAction.Stop Examining", False },
3266     { "menuFile.Mail Move", True },
3267     { "menuFile.Reload CMail Message", True },
3268     { NULL, False }
3269 };
3270
3271 Enables trainingOnEnables[] = {
3272   { "menuMode.Edit Comment", False },
3273   { "menuMode.Pause", False },
3274   { "menuStep.Forward", False },
3275   { "menuStep.Backward", False },
3276   { "menuStep.Forward to End", False },
3277   { "menuStep.Back to Start", False },
3278   { "menuStep.Move Now", False },
3279   { "menuStep.Truncate Game", False },
3280   { NULL, False }
3281 };
3282
3283 Enables trainingOffEnables[] = {
3284   { "menuMode.Edit Comment", True },
3285   { "menuMode.Pause", True },
3286   { "menuStep.Forward", True },
3287   { "menuStep.Backward", True },
3288   { "menuStep.Forward to End", True },
3289   { "menuStep.Back to Start", True },
3290   { "menuStep.Move Now", True },
3291   { "menuStep.Truncate Game", True },
3292   { NULL, False }
3293 };
3294
3295 Enables machineThinkingEnables[] = {
3296   { "menuFile.Load Game", False },
3297   { "menuFile.Load Next Game", False },
3298   { "menuFile.Load Previous Game", False },
3299   { "menuFile.Reload Same Game", False },
3300   { "menuFile.Paste Game", False },
3301   { "menuFile.Load Position", False },
3302   { "menuFile.Load Next Position", False },
3303   { "menuFile.Load Previous Position", False },
3304   { "menuFile.Reload Same Position", False },
3305   { "menuFile.Paste Position", False },
3306   { "menuMode.Machine White", False },
3307   { "menuMode.Machine Black", False },
3308   { "menuMode.Two Machines", False },
3309   { "menuStep.Retract Move", False },
3310   { NULL, False }
3311 };
3312
3313 Enables userThinkingEnables[] = {
3314   { "menuFile.Load Game", True },
3315   { "menuFile.Load Next Game", True },
3316   { "menuFile.Load Previous Game", True },
3317   { "menuFile.Reload Same Game", True },
3318   { "menuFile.Paste Game", True },
3319   { "menuFile.Load Position", True },
3320   { "menuFile.Load Next Position", True },
3321   { "menuFile.Load Previous Position", True },
3322   { "menuFile.Reload Same Position", True },
3323   { "menuFile.Paste Position", True },
3324   { "menuMode.Machine White", True },
3325   { "menuMode.Machine Black", True },
3326   { "menuMode.Two Machines", True },
3327   { "menuStep.Retract Move", True },
3328   { NULL, False }
3329 };
3330
3331 void SetICSMode()
3332 {
3333   SetMenuEnables(icsEnables);
3334
3335 #ifdef ZIPPY
3336   if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
3337      XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
3338 #endif
3339 }
3340
3341 void
3342 SetNCPMode()
3343 {
3344   SetMenuEnables(ncpEnables);
3345 }
3346
3347 void
3348 SetGNUMode()
3349 {
3350   SetMenuEnables(gnuEnables);
3351 }
3352
3353 void
3354 SetCmailMode()
3355 {
3356   SetMenuEnables(cmailEnables);
3357 }
3358
3359 void
3360 SetTrainingModeOn()
3361 {
3362   SetMenuEnables(trainingOnEnables);
3363   if (appData.showButtonBar) {
3364     XtSetSensitive(buttonBarWidget, False);
3365   }
3366   CommentPopDown();
3367 }
3368
3369 void
3370 SetTrainingModeOff()
3371 {
3372   SetMenuEnables(trainingOffEnables);
3373   if (appData.showButtonBar) {
3374     XtSetSensitive(buttonBarWidget, True);
3375   }
3376 }
3377
3378 void
3379 SetUserThinkingEnables()
3380 {
3381   if (appData.noChessProgram) return;
3382   SetMenuEnables(userThinkingEnables);
3383 }
3384
3385 void
3386 SetMachineThinkingEnables()
3387 {
3388   if (appData.noChessProgram) return;
3389   SetMenuEnables(machineThinkingEnables);
3390   switch (gameMode) {
3391   case MachinePlaysBlack:
3392   case MachinePlaysWhite:
3393   case TwoMachinesPlay:
3394     XtSetSensitive(XtNameToWidget(menuBarWidget,
3395                                   ModeToWidgetName(gameMode)), True);
3396     break;
3397   default:
3398     break;
3399   }
3400 }
3401
3402 #define Abs(n) ((n)<0 ? -(n) : (n))
3403
3404 /*
3405  * Find a font that matches "pattern" that is as close as
3406  * possible to the targetPxlSize.  Prefer fonts that are k
3407  * pixels smaller to fonts that are k pixels larger.  The
3408  * pattern must be in the X Consortium standard format,
3409  * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
3410  * The return value should be freed with XtFree when no
3411  * longer needed.
3412  */
3413 char *FindFont(pattern, targetPxlSize)
3414      char *pattern;
3415      int targetPxlSize;
3416 {
3417     char **fonts, *p, *best, *scalable, *scalableTail;
3418     int i, j, nfonts, minerr, err, pxlSize;
3419
3420 #ifdef ENABLE_NLS
3421     char **missing_list;
3422     int missing_count;
3423     char *def_string, *base_fnt_lst, strInt[3];
3424     XFontSet fntSet;
3425     XFontStruct **fnt_list;
3426
3427     base_fnt_lst = calloc(1, strlen(pattern) + 3);
3428     sprintf(strInt, "%d", targetPxlSize);
3429     p = strstr(pattern, "--");
3430     strncpy(base_fnt_lst, pattern, p - pattern + 2);
3431     strcat(base_fnt_lst, strInt);
3432     strcat(base_fnt_lst, strchr(p + 2, '-'));
3433
3434     if ((fntSet = XCreateFontSet(xDisplay,
3435                                  base_fnt_lst,
3436                                  &missing_list,
3437                                  &missing_count,
3438                                  &def_string)) == NULL) {
3439
3440        fprintf(stderr, _("Unable to create font set.\n"));
3441        exit (2);
3442     }
3443
3444     nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
3445 #else
3446     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
3447     if (nfonts < 1) {
3448         fprintf(stderr, _("%s: no fonts match pattern %s\n"),
3449                 programName, pattern);
3450         exit(2);
3451     }
3452 #endif
3453
3454     best = fonts[0];
3455     scalable = NULL;
3456     minerr = 999999;
3457     for (i=0; i<nfonts; i++) {
3458         j = 0;
3459         p = fonts[i];
3460         if (*p != '-') continue;
3461         while (j < 7) {
3462             if (*p == NULLCHAR) break;
3463             if (*p++ == '-') j++;
3464         }
3465         if (j < 7) continue;
3466         pxlSize = atoi(p);
3467         if (pxlSize == 0) {
3468             scalable = fonts[i];
3469             scalableTail = p;
3470         } else {
3471             err = pxlSize - targetPxlSize;
3472             if (Abs(err) < Abs(minerr) ||
3473                 (minerr > 0 && err < 0 && -err == minerr)) {
3474                 best = fonts[i];
3475                 minerr = err;
3476             }
3477         }
3478     }
3479     if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
3480         /* If the error is too big and there is a scalable font,
3481            use the scalable font. */
3482         int headlen = scalableTail - scalable;
3483         p = (char *) XtMalloc(strlen(scalable) + 10);
3484         while (isdigit(*scalableTail)) scalableTail++;
3485         sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
3486     } else {
3487         p = (char *) XtMalloc(strlen(best) + 1);
3488         strcpy(p, best);
3489     }
3490     if (appData.debugMode) {
3491         fprintf(debugFP, _("resolved %s at pixel size %d\n  to %s\n"),
3492                 pattern, targetPxlSize, p);
3493     }
3494 #ifdef ENABLE_NLS
3495     if (missing_count > 0)
3496        XFreeStringList(missing_list);
3497     XFreeFontSet(xDisplay, fntSet);
3498 #else
3499      XFreeFontNames(fonts);
3500 #endif
3501     return p;
3502 }
3503
3504 void CreateGCs()
3505 {
3506     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
3507       | GCBackground | GCFunction | GCPlaneMask;
3508     XGCValues gc_values;
3509     GC copyInvertedGC;
3510
3511     gc_values.plane_mask = AllPlanes;
3512     gc_values.line_width = lineGap;
3513     gc_values.line_style = LineSolid;
3514     gc_values.function = GXcopy;
3515
3516     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3517     gc_values.background = XBlackPixel(xDisplay, xScreen);
3518     lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3519
3520     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3521     gc_values.background = XWhitePixel(xDisplay, xScreen);
3522     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
3523     XSetFont(xDisplay, coordGC, coordFontID);
3524
3525     // [HGM] make font for holdings counts (white on black0
3526     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3527     gc_values.background = XBlackPixel(xDisplay, xScreen);
3528     countGC = XtGetGC(shellWidget, value_mask, &gc_values);
3529     XSetFont(xDisplay, countGC, countFontID);
3530
3531     if (appData.monoMode) {
3532         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3533         gc_values.background = XWhitePixel(xDisplay, xScreen);
3534         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3535
3536         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3537         gc_values.background = XBlackPixel(xDisplay, xScreen);
3538         lightSquareGC = wbPieceGC
3539           = XtGetGC(shellWidget, value_mask, &gc_values);
3540
3541         gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3542         gc_values.background = XWhitePixel(xDisplay, xScreen);
3543         darkSquareGC = bwPieceGC
3544           = XtGetGC(shellWidget, value_mask, &gc_values);
3545
3546         if (DefaultDepth(xDisplay, xScreen) == 1) {
3547             /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
3548             gc_values.function = GXcopyInverted;
3549             copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
3550             gc_values.function = GXcopy;
3551             if (XBlackPixel(xDisplay, xScreen) == 1) {
3552                 bwPieceGC = darkSquareGC;
3553                 wbPieceGC = copyInvertedGC;
3554             } else {
3555                 bwPieceGC = copyInvertedGC;
3556                 wbPieceGC = lightSquareGC;
3557             }
3558         }
3559     } else {
3560         gc_values.foreground = highlightSquareColor;
3561         gc_values.background = highlightSquareColor;
3562         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3563
3564         gc_values.foreground = premoveHighlightColor;
3565         gc_values.background = premoveHighlightColor;
3566         prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3567
3568         gc_values.foreground = lightSquareColor;
3569         gc_values.background = darkSquareColor;
3570         lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3571
3572         gc_values.foreground = darkSquareColor;
3573         gc_values.background = lightSquareColor;
3574         darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3575
3576         gc_values.foreground = jailSquareColor;
3577         gc_values.background = jailSquareColor;
3578         jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3579
3580         gc_values.foreground = whitePieceColor;
3581         gc_values.background = darkSquareColor;
3582         wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3583
3584         gc_values.foreground = whitePieceColor;
3585         gc_values.background = lightSquareColor;
3586         wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3587
3588         gc_values.foreground = whitePieceColor;
3589         gc_values.background = jailSquareColor;
3590         wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3591
3592         gc_values.foreground = blackPieceColor;
3593         gc_values.background = darkSquareColor;
3594         bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3595
3596         gc_values.foreground = blackPieceColor;
3597         gc_values.background = lightSquareColor;
3598         blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3599
3600         gc_values.foreground = blackPieceColor;
3601         gc_values.background = jailSquareColor;
3602         bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3603     }
3604 }
3605
3606 void loadXIM(xim, xmask, filename, dest, mask)
3607      XImage *xim;
3608      XImage *xmask;
3609      char *filename;
3610      Pixmap *dest;
3611      Pixmap *mask;
3612 {
3613     int x, y, w, h, p;
3614     FILE *fp;
3615     Pixmap temp;
3616     XGCValues   values;
3617     GC maskGC;
3618
3619     fp = fopen(filename, "rb");
3620     if (!fp) {
3621         fprintf(stderr, _("%s: error loading XIM!\n"), programName);
3622         exit(1);
3623     }
3624
3625     w = fgetc(fp);
3626     h = fgetc(fp);
3627
3628     for (y=0; y<h; ++y) {
3629         for (x=0; x<h; ++x) {
3630             p = fgetc(fp);
3631
3632             switch (p) {
3633               case 0:
3634                 XPutPixel(xim, x, y, blackPieceColor);
3635                 if (xmask)
3636                   XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
3637                 break;
3638               case 1:
3639                 XPutPixel(xim, x, y, darkSquareColor);
3640                 if (xmask)
3641                   XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
3642                 break;
3643               case 2:
3644                 XPutPixel(xim, x, y, whitePieceColor);
3645                 if (xmask)
3646                   XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
3647                 break;
3648               case 3:
3649                 XPutPixel(xim, x, y, lightSquareColor);
3650                 if (xmask)
3651                   XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
3652                 break;
3653             }
3654         }
3655     }
3656
3657     /* create Pixmap of piece */
3658     *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
3659                           w, h, xim->depth);
3660     XPutImage(xDisplay, *dest, lightSquareGC, xim,
3661               0, 0, 0, 0, w, h);
3662
3663     /* create Pixmap of clipmask
3664        Note: We assume the white/black pieces have the same
3665              outline, so we make only 6 masks. This is okay
3666              since the XPM clipmask routines do the same. */
3667     if (xmask) {
3668       temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
3669                             w, h, xim->depth);
3670       XPutImage(xDisplay, temp, lightSquareGC, xmask,
3671               0, 0, 0, 0, w, h);
3672
3673       /* now create the 1-bit version */
3674       *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
3675                           w, h, 1);
3676
3677       values.foreground = 1;
3678       values.background = 0;
3679
3680       /* Don't use XtGetGC, not read only */
3681       maskGC = XCreateGC(xDisplay, *mask,
3682                     GCForeground | GCBackground, &values);
3683       XCopyPlane(xDisplay, temp, *mask, maskGC,
3684                   0, 0, squareSize, squareSize, 0, 0, 1);
3685       XFreePixmap(xDisplay, temp);
3686     }
3687 }
3688
3689 void CreateXIMPieces()
3690 {
3691     int piece, kind;
3692     char buf[MSG_SIZ];
3693     u_int ss;
3694     static char *ximkind[] = { "ll", "ld", "dl", "dd" };
3695     XImage *ximtemp;
3696
3697     ss = squareSize;
3698
3699     /* The XSynchronize calls were copied from CreatePieces.
3700        Not sure if needed, but can't hurt */
3701     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
3702                                      buffering bug */
3703
3704     /* temp needed by loadXIM() */
3705     ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3706                  0, 0, ss, ss, AllPlanes, XYPixmap);
3707
3708     if (strlen(appData.pixmapDirectory) == 0) {
3709       useImages = 0;
3710     } else {
3711         useImages = 1;
3712         if (appData.monoMode) {
3713           DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
3714                             0, 2);
3715           ExitEvent(2);
3716         }
3717         fprintf(stderr, _("\nLoading XIMs...\n"));
3718         /* Load pieces */
3719         for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
3720             fprintf(stderr, "%d", piece+1);
3721             for (kind=0; kind<4; kind++) {
3722                 fprintf(stderr, ".");
3723                 snprintf(buf, sizeof(buf), "%s/%c%s%u.xim",
3724                         ExpandPathName(appData.pixmapDirectory),
3725                         ToLower(PieceToChar((ChessSquare)piece)),
3726                         ximkind[kind], ss);
3727                 ximPieceBitmap[kind][piece] =
3728                   XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3729                             0, 0, ss, ss, AllPlanes, XYPixmap);
3730                 if (appData.debugMode)
3731                   fprintf(stderr, _("(File:%s:) "), buf);
3732                 loadXIM(ximPieceBitmap[kind][piece],
3733                         ximtemp, buf,
3734                         &(xpmPieceBitmap[kind][piece]),
3735                         &(ximMaskPm[piece%(int)BlackPawn]));
3736             }
3737             fprintf(stderr," ");
3738         }
3739         /* Load light and dark squares */
3740         /* If the LSQ and DSQ pieces don't exist, we will
3741            draw them with solid squares. */
3742         snprintf(buf,sizeof(buf), "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
3743         if (access(buf, 0) != 0) {
3744             useImageSqs = 0;
3745         } else {
3746             useImageSqs = 1;
3747             fprintf(stderr, _("light square "));
3748             ximLightSquare=
3749               XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3750                         0, 0, ss, ss, AllPlanes, XYPixmap);
3751             if (appData.debugMode)
3752               fprintf(stderr, _("(File:%s:) "), buf);
3753
3754             loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
3755             fprintf(stderr, _("dark square "));
3756             snprintf(buf,sizeof(buf), "%s/dsq%u.xim",
3757                     ExpandPathName(appData.pixmapDirectory), ss);
3758             if (appData.debugMode)
3759               fprintf(stderr, _("(File:%s:) "), buf);
3760             ximDarkSquare=
3761               XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3762                         0, 0, ss, ss, AllPlanes, XYPixmap);
3763             loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
3764             xpmJailSquare = xpmLightSquare;
3765         }
3766         fprintf(stderr, _("Done.\n"));
3767     }
3768     XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
3769 }
3770
3771 #if HAVE_LIBXPM
3772 void CreateXPMPieces()
3773 {
3774     int piece, kind, r;
3775     char buf[MSG_SIZ];
3776     u_int ss = squareSize;
3777     XpmAttributes attr;
3778     static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
3779     XpmColorSymbol symbols[4];
3780
3781 #if 0
3782     /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
3783     if (appData.debugMode) {
3784         fprintf(stderr, "XPM Library Version: %d.%d%c\n",
3785                 XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
3786     }
3787 #endif
3788
3789     /* The XSynchronize calls were copied from CreatePieces.
3790        Not sure if needed, but can't hurt */
3791     XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
3792
3793     /* Setup translations so piece colors match square colors */
3794     symbols[0].name = "light_piece";
3795     symbols[0].value = appData.whitePieceColor;
3796     symbols[1].name = "dark_piece";
3797     symbols[1].value = appData.blackPieceColor;
3798     symbols[2].name = "light_square";
3799     symbols[2].value = appData.lightSquareColor;
3800     symbols[3].name = "dark_square";
3801     symbols[3].value = appData.darkSquareColor;
3802
3803     attr.valuemask = XpmColorSymbols;
3804     attr.colorsymbols = symbols;
3805     attr.numsymbols = 4;
3806
3807     if (appData.monoMode) {
3808       DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
3809                         0, 2);
3810       ExitEvent(2);
3811     }
3812     if (strlen(appData.pixmapDirectory) == 0) {
3813         XpmPieces* pieces = builtInXpms;
3814         useImages = 1;
3815         /* Load pieces */
3816         while (pieces->size != squareSize && pieces->size) pieces++;
3817         if (!pieces->size) {
3818           fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
3819           exit(1);
3820         }
3821         for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
3822             for (kind=0; kind<4; kind++) {
3823
3824                 if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
3825                                                pieces->xpm[piece][kind],
3826                                                &(xpmPieceBitmap[kind][piece]),
3827                                                NULL, &attr)) != 0) {
3828                   fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
3829                           r, buf);
3830                   exit(1);
3831                 }
3832             }
3833         }
3834         useImageSqs = 0;
3835         xpmJailSquare = xpmLightSquare;
3836     } else {
3837         useImages = 1;
3838
3839         fprintf(stderr, _("\nLoading XPMs...\n"));
3840
3841         /* Load pieces */
3842         for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
3843             fprintf(stderr, "%d ", piece+1);
3844             for (kind=0; kind<4; kind++) {
3845               snprintf(buf, sizeof(buf), "%s/%c%s%u.xpm",
3846                         ExpandPathName(appData.pixmapDirectory),
3847                         ToLower(PieceToChar((ChessSquare)piece)),
3848                         xpmkind[kind], ss);
3849                 if (appData.debugMode) {
3850                     fprintf(stderr, _("(File:%s:) "), buf);
3851                 }
3852                 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
3853                                            &(xpmPieceBitmap[kind][piece]),
3854                                            NULL, &attr)) != 0) {
3855                     fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
3856                             r, buf);
3857                     exit(1);
3858                 }
3859             }
3860         }
3861         /* Load light and dark squares */
3862         /* If the LSQ and DSQ pieces don't exist, we will
3863            draw them with solid squares. */
3864         fprintf(stderr, _("light square "));
3865         snprintf(buf, sizeof(buf), "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
3866         if (access(buf, 0) != 0) {
3867             useImageSqs = 0;
3868         } else {
3869             useImageSqs = 1;
3870             if (appData.debugMode)
3871               fprintf(stderr, _("(File:%s:) "), buf);
3872
3873             if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
3874                                        &xpmLightSquare, NULL, &attr)) != 0) {
3875                 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
3876                 exit(1);
3877             }
3878             fprintf(stderr, _("dark square "));
3879             snprintf(buf, sizeof(buf), "%s/dsq%u.xpm",
3880                     ExpandPathName(appData.pixmapDirectory), ss);
3881             if (appData.debugMode) {
3882                 fprintf(stderr, _("(File:%s:) "), buf);
3883             }
3884             if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
3885                                        &xpmDarkSquare, NULL, &attr)) != 0) {
3886                 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
3887                 exit(1);
3888             }
3889         }
3890         xpmJailSquare = xpmLightSquare;
3891         fprintf(stderr, _("Done.\n"));
3892     }
3893     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
3894                                       buffering bug */
3895 }
3896 #endif /* HAVE_LIBXPM */
3897
3898 #if HAVE_LIBXPM
3899 /* No built-in bitmaps */
3900 void CreatePieces()
3901 {
3902     int piece, kind;
3903     char buf[MSG_SIZ];
3904     u_int ss = squareSize;
3905
3906     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
3907                                      buffering bug */
3908
3909     for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
3910         for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
3911             sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
3912                     ss, kind == SOLID ? 's' : 'o');
3913             ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);
3914         }
3915     }
3916
3917     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
3918                                       buffering bug */
3919 }
3920 #else
3921 /* With built-in bitmaps */
3922 void CreatePieces()
3923 {
3924     BuiltInBits* bib = builtInBits;
3925     int piece, kind;
3926     char buf[MSG_SIZ];
3927     u_int ss = squareSize;
3928
3929     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
3930                                      buffering bug */
3931
3932     while (bib->squareSize != ss && bib->squareSize != 0) bib++;
3933
3934     for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
3935         for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
3936             sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
3937                     ss, kind == SOLID ? 's' : 'o');
3938             ReadBitmap(&pieceBitmap[kind][piece], buf,
3939                        bib->bits[kind][piece], ss, ss);
3940         }
3941     }
3942
3943     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
3944                                       buffering bug */
3945 }
3946 #endif
3947
3948 void ReadBitmap(pm, name, bits, wreq, hreq)
3949      Pixmap *pm;
3950      String name;
3951      unsigned char bits[];
3952      u_int wreq, hreq;
3953 {
3954     int x_hot, y_hot;
3955     u_int w, h;
3956     int errcode;
3957     char msg[MSG_SIZ], fullname[MSG_SIZ];
3958
3959     if (*appData.bitmapDirectory != NULLCHAR) {
3960         strcpy(fullname, appData.bitmapDirectory);
3961         strcat(fullname, "/");
3962         strcat(fullname, name);
3963         errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
3964                                   &w, &h, pm, &x_hot, &y_hot);
3965         if (errcode != BitmapSuccess) {
3966             switch (errcode) {
3967               case BitmapOpenFailed:
3968                 snprintf(msg, sizeof(msg), _("Can't open bitmap file %s"), fullname);
3969                 break;
3970               case BitmapFileInvalid:
3971                 snprintf(msg, sizeof(msg), _("Invalid bitmap in file %s"), fullname);
3972                 break;
3973               case BitmapNoMemory:
3974                 snprintf(msg, sizeof(msg), _("Ran out of memory reading bitmap file %s"),
3975                         fullname);
3976                 break;
3977               default:
3978                 snprintf(msg, sizeof(msg), _("Unknown XReadBitmapFile error %d on file %s"),
3979                         errcode, fullname);
3980                 break;
3981             }
3982             fprintf(stderr, _("%s: %s...using built-in\n"),
3983                     programName, msg);
3984         } else if (w != wreq || h != hreq) {
3985             fprintf(stderr,
3986                     _("%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n"),
3987                     programName, fullname, w, h, wreq, hreq);
3988         } else {
3989             return;
3990         }
3991     }
3992     if (bits == NULL) {
3993 #if 0
3994         fprintf(stderr, _("%s: No built-in bitmap for %s; giving up\n"),
3995                 programName, name);
3996         exit(1);
3997 #endif
3998         ; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
3999     } else {
4000         *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
4001                                     wreq, hreq);
4002     }
4003 }
4004
4005 void CreateGrid()
4006 {
4007     int i, j;
4008
4009     if (lineGap == 0) return;
4010
4011     /* [HR] Split this into 2 loops for non-square boards. */
4012
4013     for (i = 0; i < BOARD_HEIGHT + 1; i++) {
4014         gridSegments[i].x1 = 0;
4015         gridSegments[i].x2 =
4016           lineGap + BOARD_WIDTH * (squareSize + lineGap);
4017         gridSegments[i].y1 = gridSegments[i].y2
4018           = lineGap / 2 + (i * (squareSize + lineGap));
4019     }
4020
4021     for (j = 0; j < BOARD_WIDTH + 1; j++) {
4022         gridSegments[j + i].y1 = 0;
4023         gridSegments[j + i].y2 =
4024           lineGap + BOARD_HEIGHT * (squareSize + lineGap);
4025         gridSegments[j + i].x1 = gridSegments[j + i].x2
4026           = lineGap / 2 + (j * (squareSize + lineGap));
4027     }
4028 }
4029
4030 static void MenuBarSelect(w, addr, index)
4031      Widget w;
4032      caddr_t addr;
4033      caddr_t index;
4034 {
4035     XtActionProc proc = (XtActionProc) addr;
4036
4037     (proc)(NULL, NULL, NULL, NULL);
4038 }
4039
4040 void CreateMenuBarPopup(parent, name, mb)
4041      Widget parent;
4042      String name;
4043      Menu *mb;
4044 {
4045     int j;
4046     Widget menu, entry;
4047     MenuItem *mi;
4048     Arg args[16];
4049
4050     menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
4051                               parent, NULL, 0);
4052     j = 0;
4053     XtSetArg(args[j], XtNleftMargin, 20);   j++;
4054     XtSetArg(args[j], XtNrightMargin, 20);  j++;
4055     mi = mb->mi;
4056     while (mi->string != NULL) {
4057         if (strcmp(mi->string, "----") == 0) {
4058             entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
4059                                           menu, args, j);
4060         } else {
4061           XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
4062             entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
4063                                           menu, args, j+1);
4064             XtAddCallback(entry, XtNcallback,
4065                           (XtCallbackProc) MenuBarSelect,
4066                           (caddr_t) mi->proc);
4067         }
4068         mi++;
4069     }
4070 }
4071
4072 Widget CreateMenuBar(mb)
4073      Menu *mb;
4074 {
4075     int j;
4076     Widget anchor, menuBar;
4077     Arg args[16];
4078     char menuName[MSG_SIZ];
4079
4080     j = 0;
4081     XtSetArg(args[j], XtNorientation, XtorientHorizontal);  j++;
4082     XtSetArg(args[j], XtNvSpace, 0);                        j++;
4083     XtSetArg(args[j], XtNborderWidth, 0);                   j++;
4084     menuBar = XtCreateWidget("menuBar", boxWidgetClass,
4085                              formWidget, args, j);
4086
4087     while (mb->name != NULL) {
4088         strcpy(menuName, "menu");
4089         strcat(menuName, mb->name);
4090         j = 0;
4091         XtSetArg(args[j], XtNmenuName, XtNewString(menuName));  j++;
4092         if (tinyLayout) {
4093             char shortName[2];
4094             shortName[0] = _(mb->name)[0];
4095             shortName[1] = NULLCHAR;
4096             XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
4097         }
4098       else {
4099           XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++;
4100       }
4101
4102         XtSetArg(args[j], XtNborderWidth, 0);                   j++;
4103         anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
4104                                        menuBar, args, j);
4105         CreateMenuBarPopup(menuBar, menuName, mb);
4106         mb++;
4107     }
4108     return menuBar;
4109 }