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