changed click-click moves
[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 #ifdef ZIPPY
1026     { "zippyTalk", "zippyTalk", XtRBoolean,
1027         sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
1028         XtRImmediate, (XtPointer) ZIPPY_TALK },
1029     { "zippyPlay", "zippyPlay", XtRBoolean,
1030         sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
1031         XtRImmediate, (XtPointer) ZIPPY_PLAY },
1032     { "zippyLines", "zippyLines", XtRString, sizeof(String),
1033         XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
1034     { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
1035         XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
1036     { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
1037         XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
1038     { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
1039         XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
1040     { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
1041         XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
1042         ZIPPY_WRONG_PASSWORD },
1043     { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
1044         XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
1045     { "zippyUseI", "zippyUseI", XtRBoolean,
1046         sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
1047         XtRImmediate, (XtPointer) ZIPPY_USE_I },
1048     { "zippyBughouse", "zippyBughouse", XtRInt,
1049         sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
1050         XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
1051     { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
1052         sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
1053         XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
1054     { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
1055         XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
1056     { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
1057         XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
1058     { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
1059         sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
1060         XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
1061     { "zippyAbort", "zippyAbort", XtRBoolean,
1062         sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
1063         XtRImmediate, (XtPointer) ZIPPY_ABORT },
1064     { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
1065         XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
1066     { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
1067         XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
1068         (XtPointer) ZIPPY_MAX_GAMES },
1069     { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
1070         XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
1071         (XtPointer) ZIPPY_REPLAY_TIMEOUT },
1072     { "zippyShortGame", "zippyShortGame", XtRInt, sizeof(int),
1073         XtOffset(AppDataPtr, zippyShortGame), XtRImmediate,
1074         (XtPointer) 0 },
1075 #endif
1076     { "flashCount", "flashCount", XtRInt, sizeof(int),
1077         XtOffset(AppDataPtr, flashCount), XtRImmediate,
1078         (XtPointer) FLASH_COUNT  },
1079     { "flashRate", "flashRate", XtRInt, sizeof(int),
1080         XtOffset(AppDataPtr, flashRate), XtRImmediate,
1081         (XtPointer) FLASH_RATE },
1082     { "pixmapDirectory", "pixmapDirectory", XtRString,
1083         sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
1084         XtRString, "" },
1085     { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
1086         XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
1087         (XtPointer) MS_LOGIN_DELAY },
1088     { "colorizeMessages", "colorizeMessages", XtRBoolean,
1089         sizeof(Boolean), XtOffset(AppDataPtr, colorize),
1090         XtRImmediate, (XtPointer) False },
1091     { "colorShout", "colorShout", XtRString,
1092         sizeof(String), XtOffset(AppDataPtr, colorShout),
1093         XtRString, COLOR_SHOUT },
1094     { "colorSShout", "colorSShout", XtRString,
1095         sizeof(String), XtOffset(AppDataPtr, colorSShout),
1096         XtRString, COLOR_SSHOUT },
1097     { "colorChannel1", "colorChannel1", XtRString,
1098         sizeof(String), XtOffset(AppDataPtr, colorChannel1),
1099         XtRString, COLOR_CHANNEL1 },
1100     { "colorChannel", "colorChannel", XtRString,
1101         sizeof(String), XtOffset(AppDataPtr, colorChannel),
1102         XtRString, COLOR_CHANNEL },
1103     { "colorKibitz", "colorKibitz", XtRString,
1104         sizeof(String), XtOffset(AppDataPtr, colorKibitz),
1105         XtRString, COLOR_KIBITZ },
1106     { "colorTell", "colorTell", XtRString,
1107         sizeof(String), XtOffset(AppDataPtr, colorTell),
1108         XtRString, COLOR_TELL },
1109     { "colorChallenge", "colorChallenge", XtRString,
1110         sizeof(String), XtOffset(AppDataPtr, colorChallenge),
1111         XtRString, COLOR_CHALLENGE },
1112     { "colorRequest", "colorRequest", XtRString,
1113         sizeof(String), XtOffset(AppDataPtr, colorRequest),
1114         XtRString, COLOR_REQUEST },
1115     { "colorSeek", "colorSeek", XtRString,
1116         sizeof(String), XtOffset(AppDataPtr, colorSeek),
1117         XtRString, COLOR_SEEK },
1118     { "colorNormal", "colorNormal", XtRString,
1119         sizeof(String), XtOffset(AppDataPtr, colorNormal),
1120         XtRString, COLOR_NORMAL },
1121     { "soundProgram", "soundProgram", XtRString,
1122       sizeof(String), XtOffset(AppDataPtr, soundProgram),
1123       XtRString, "play" },
1124     { "soundShout", "soundShout", XtRString,
1125       sizeof(String), XtOffset(AppDataPtr, soundShout),
1126       XtRString, "" },
1127     { "soundSShout", "soundSShout", XtRString,
1128       sizeof(String), XtOffset(AppDataPtr, soundSShout),
1129       XtRString, "" },
1130     { "soundChannel1", "soundChannel1", XtRString,
1131       sizeof(String), XtOffset(AppDataPtr, soundChannel1),
1132       XtRString, "" },
1133     { "soundChannel", "soundChannel", XtRString,
1134       sizeof(String), XtOffset(AppDataPtr, soundChannel),
1135       XtRString, "" },
1136     { "soundKibitz", "soundKibitz", XtRString,
1137       sizeof(String), XtOffset(AppDataPtr, soundKibitz),
1138       XtRString, "" },
1139     { "soundTell", "soundTell", XtRString,
1140       sizeof(String), XtOffset(AppDataPtr, soundTell),
1141       XtRString, "" },
1142     { "soundChallenge", "soundChallenge", XtRString,
1143       sizeof(String), XtOffset(AppDataPtr, soundChallenge),
1144       XtRString, "" },
1145     { "soundRequest", "soundRequest", XtRString,
1146       sizeof(String), XtOffset(AppDataPtr, soundRequest),
1147       XtRString, "" },
1148     { "soundSeek", "soundSeek", XtRString,
1149       sizeof(String), XtOffset(AppDataPtr, soundSeek),
1150       XtRString, "" },
1151     { "soundMove", "soundMove", XtRString,
1152       sizeof(String), XtOffset(AppDataPtr, soundMove),
1153       XtRString, "$" },
1154     { "soundIcsWin", "soundIcsWin", XtRString,
1155       sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
1156       XtRString, "" },
1157     { "soundIcsLoss", "soundIcsLoss", XtRString,
1158       sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
1159       XtRString, "" },
1160     { "soundIcsDraw", "soundIcsDraw", XtRString,
1161       sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
1162       XtRString, "" },
1163     { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
1164       sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
1165       XtRString, "" },
1166     { "soundIcsAlarm", "soundIcsAlarm", XtRString,
1167       sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
1168       XtRString, "$" },
1169     { "reuseFirst", "reuseFirst", XtRBoolean,
1170         sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
1171         XtRImmediate, (XtPointer) True },
1172     { "reuseSecond", "reuseSecond", XtRBoolean,
1173         sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
1174         XtRImmediate, (XtPointer) True },
1175     { "animateDragging", "animateDragging", XtRBoolean,
1176         sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
1177         XtRImmediate, (XtPointer) True },
1178     { "animateMoving", "animateMoving", XtRBoolean,
1179         sizeof(Boolean), XtOffset(AppDataPtr, animate),
1180         XtRImmediate, (XtPointer) True },
1181     { "animateSpeed", "animateSpeed", XtRInt,
1182         sizeof(int), XtOffset(AppDataPtr, animSpeed),
1183         XtRImmediate, (XtPointer)10 },
1184     { "popupExitMessage", "popupExitMessage", XtRBoolean,
1185         sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
1186         XtRImmediate, (XtPointer) True },
1187     { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
1188         sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
1189         XtRImmediate, (XtPointer) False },
1190     { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
1191         sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
1192         XtRImmediate, (XtPointer)4 },
1193     { "initialMode", "initialMode", XtRString,
1194         sizeof(String), XtOffset(AppDataPtr, initialMode),
1195         XtRImmediate, (XtPointer) "" },
1196     { "variant", "variant", XtRString,
1197         sizeof(String), XtOffset(AppDataPtr, variant),
1198         XtRImmediate, (XtPointer) "normal" },
1199     { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
1200         sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
1201         XtRImmediate, (XtPointer)PROTOVER },
1202     { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
1203         sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
1204         XtRImmediate, (XtPointer)PROTOVER },
1205     { "showButtonBar", "showButtonBar", XtRBoolean,
1206         sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
1207         XtRImmediate, (XtPointer) True },
1208     { "lowTimeWarningColor", "lowTimeWarningColor", XtRString,
1209       sizeof(String), XtOffset(AppDataPtr, lowTimeWarningColor),
1210       XtRString, COLOR_LOWTIMEWARNING },
1211     { "lowTimeWarning", "lowTimeWarning", XtRBoolean,
1212       sizeof(Boolean), XtOffset(AppDataPtr, lowTimeWarning),
1213       XtRImmediate, (XtPointer) False },
1214     {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean,        /* [DM] icsEngineAnalyze */
1215         sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
1216         XtRImmediate, (XtPointer) False },
1217     { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
1218         sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
1219         XtRImmediate, (XtPointer) False },
1220     { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
1221         sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
1222         XtRImmediate, (XtPointer) False },
1223     { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
1224         sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
1225         XtRImmediate, (XtPointer) False },
1226     { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
1227         sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
1228         XtRImmediate, (XtPointer) True },
1229     { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
1230         sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
1231         XtRImmediate, (XtPointer) 0},
1232     { "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 int
2324 main(argc, argv)
2325      int argc;
2326      char **argv;
2327 {
2328     int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
2329     XSetWindowAttributes window_attributes;
2330     Arg args[16];
2331     Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2332     XrmValue vFrom, vTo;
2333     XtGeometryResult gres;
2334     char *p;
2335     XrmDatabase xdb;
2336     int forceMono = False;
2337 #define INDIRECTION
2338 #ifdef INDIRECTION
2339     // [HGM] before anything else, expand any indirection files amongst options
2340     char *argvCopy[1000]; // 1000 seems enough
2341     char newArgs[10000];  // holds actual characters
2342     int k = 0;
2343
2344     srandom(time(0)); // [HGM] book: make random truly random
2345
2346     j = 0;
2347     for(i=0; i<argc; i++) {
2348         if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2349 //fprintf(stderr, "arg %s\n", argv[i]);
2350         if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
2351             char c;
2352             FILE *f = fopen(argv[i]+1, "rb");
2353             if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
2354             argvCopy[j++] = newArgs + k; // get ready for first argument from file
2355             while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
2356                 if(c == '\n') {
2357                     if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2358                     newArgs[k++] = 0;  // terminate current arg
2359                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2360                     argvCopy[j++] = newArgs + k; // get ready for next
2361                 } else {
2362                     if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2363                     newArgs[k++] = c;
2364                 }
2365             }
2366             newArgs[k] = 0;
2367             j--;
2368             fclose(f);
2369         }
2370     }
2371     argvCopy[j] = NULL;
2372     argv = argvCopy;
2373     argc = j;
2374 #if 0
2375     if(appData.debugMode,1) { // OK, appData is not initialized here yet...
2376         for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
2377     }
2378 #endif
2379 #endif
2380
2381
2382     setbuf(stdout, NULL);
2383     setbuf(stderr, NULL);
2384     debugFP = stderr;
2385
2386     programName = strrchr(argv[0], '/');
2387     if (programName == NULL)
2388       programName = argv[0];
2389     else
2390       programName++;
2391
2392 #ifdef ENABLE_NLS
2393     XtSetLanguageProc(NULL, NULL, NULL);
2394     bindtextdomain(PACKAGE, LOCALEDIR);
2395     textdomain(PACKAGE);
2396 #endif
2397
2398     shellWidget =
2399       XtAppInitialize(&appContext, "XBoard", shellOptions,
2400                       XtNumber(shellOptions),
2401                       &argc, argv, xboardResources, NULL, 0);
2402     if (argc > 1) {
2403         fprintf(stderr, _("%s: unrecognized argument %s\n"),
2404                 programName, argv[1]);
2405         fprintf(stderr, "Recognized options:\n");
2406         for(i = 0; i < XtNumber(shellOptions); i++) {
2407             j = fprintf(stderr, "  %s%s", shellOptions[i].option,
2408                         (shellOptions[i].argKind == XrmoptionSepArg
2409                          ? " ARG" : ""));
2410             if (i++ < XtNumber(shellOptions)) {
2411                 fprintf(stderr, "%*c%s%s\n", 40 - j, ' ',
2412                         shellOptions[i].option,
2413                         (shellOptions[i].argKind == XrmoptionSepArg
2414                          ? " ARG" : ""));
2415             } else {
2416                 fprintf(stderr, "\n");
2417             }
2418         }
2419         exit(2);
2420     }
2421
2422     if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
2423         chessDir = ".";
2424     } else {
2425         if (chdir(chessDir) != 0) {
2426             fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
2427             perror(chessDir);
2428             exit(1);
2429         }
2430     }
2431
2432     p = getenv("HOME");
2433     if (p == NULL) p = "/tmp";
2434     i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
2435     gameCopyFilename = (char*) malloc(i);
2436     gamePasteFilename = (char*) malloc(i);
2437     snprintf(gameCopyFilename,i, "%s/.xboard%05uc.pgn", p, getpid());
2438     snprintf(gamePasteFilename,i, "%s/.xboard%05up.pgn", p, getpid());
2439
2440     XtGetApplicationResources(shellWidget, (XtPointer) &appData,
2441                               clientResources, XtNumber(clientResources),
2442                               NULL, 0);
2443
2444     if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
2445         /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
2446         if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
2447            printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
2448            exit(errno);
2449         }
2450         setbuf(debugFP, NULL);
2451     }
2452
2453     /* [HGM,HR] make sure board size is acceptable */
2454     if(appData.NrFiles > BOARD_SIZE ||
2455        appData.NrRanks > BOARD_SIZE   )
2456          DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
2457
2458 #if !HIGHDRAG
2459     /* This feature does not work; animation needs a rewrite */
2460     appData.highlightDragging = FALSE;
2461 #endif
2462     InitBackEnd1();
2463
2464     xDisplay = XtDisplay(shellWidget);
2465     xScreen = DefaultScreen(xDisplay);
2466     wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
2467
2468         gameInfo.variant = StringToVariant(appData.variant);
2469         InitPosition(FALSE);
2470 #if 0
2471     /*
2472      * Determine boardSize
2473      */
2474     gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
2475
2476 //#ifndef IDSIZE
2477     // [HGM] as long as we have not created the possibility to change size while running, start with requested size
2478     gameInfo.boardWidth    = appData.NrFiles > 0 ? appData.NrFiles : 8;
2479     gameInfo.boardHeight   = appData.NrRanks > 0 ? appData.NrRanks : 8;
2480     gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
2481 #endif
2482
2483
2484 #ifdef IDSIZE
2485     InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
2486 #else
2487     if (isdigit(appData.boardSize[0])) {
2488         i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
2489                    &lineGap, &clockFontPxlSize, &coordFontPxlSize,
2490                    &fontPxlSize, &smallLayout, &tinyLayout);
2491         if (i == 0) {
2492             fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
2493                     programName, appData.boardSize);
2494             exit(2);
2495         }
2496         if (i < 7) {
2497             /* Find some defaults; use the nearest known size */
2498             SizeDefaults *szd, *nearest;
2499             int distance = 99999;
2500             nearest = szd = sizeDefaults;
2501             while (szd->name != NULL) {
2502                 if (abs(szd->squareSize - squareSize) < distance) {
2503                     nearest = szd;
2504                     distance = abs(szd->squareSize - squareSize);
2505                     if (distance == 0) break;
2506                 }
2507                 szd++;
2508             }
2509             if (i < 2) lineGap = nearest->lineGap;
2510             if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
2511             if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
2512             if (i < 5) fontPxlSize = nearest->fontPxlSize;
2513             if (i < 6) smallLayout = nearest->smallLayout;
2514             if (i < 7) tinyLayout = nearest->tinyLayout;
2515         }
2516     } else {
2517         SizeDefaults *szd = sizeDefaults;
2518         if (*appData.boardSize == NULLCHAR) {
2519             while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
2520                    DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
2521               szd++;
2522             }
2523             if (szd->name == NULL) szd--;
2524         } else {
2525             while (szd->name != NULL &&
2526                    StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
2527             if (szd->name == NULL) {
2528                 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
2529                         programName, appData.boardSize);
2530                 exit(2);
2531             }
2532         }
2533         squareSize = szd->squareSize;
2534         lineGap = szd->lineGap;
2535         clockFontPxlSize = szd->clockFontPxlSize;
2536         coordFontPxlSize = szd->coordFontPxlSize;
2537         fontPxlSize = szd->fontPxlSize;
2538         smallLayout = szd->smallLayout;
2539         tinyLayout = szd->tinyLayout;
2540     }
2541
2542     /* Now, using squareSize as a hint, find a good XPM/XIM set size */
2543     if (strlen(appData.pixmapDirectory) > 0) {
2544         p = ExpandPathName(appData.pixmapDirectory);
2545         if (!p) {
2546             fprintf(stderr, _("Error expanding path name \"%s\"\n"),
2547                    appData.pixmapDirectory);
2548             exit(1);
2549         }
2550         if (appData.debugMode) {
2551           fprintf(stderr, _("\
2552 XBoard square size (hint): %d\n\
2553 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
2554         }
2555         squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
2556         if (appData.debugMode) {
2557             fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
2558         }
2559     }
2560
2561     /* [HR] height treated separately (hacked) */
2562     boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2563     boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2564     if (appData.showJail == 1) {
2565         /* Jail on top and bottom */
2566         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2567         XtSetArg(boardArgs[2], XtNheight,
2568                  boardHeight + 2*(lineGap + squareSize));
2569     } else if (appData.showJail == 2) {
2570         /* Jail on sides */
2571         XtSetArg(boardArgs[1], XtNwidth,
2572                  boardWidth + 2*(lineGap + squareSize));
2573         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2574     } else {
2575         /* No jail */
2576         XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2577         XtSetArg(boardArgs[2], XtNheight, boardHeight);
2578     }
2579
2580     /*
2581      * Determine what fonts to use.
2582      */
2583     appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
2584     clockFontID = XLoadFont(xDisplay, appData.clockFont);
2585     clockFontStruct = XQueryFont(xDisplay, clockFontID);
2586     appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
2587     coordFontID = XLoadFont(xDisplay, appData.coordFont);
2588     coordFontStruct = XQueryFont(xDisplay, coordFontID);
2589     appData.font = FindFont(appData.font, fontPxlSize);
2590     countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
2591     countFontStruct = XQueryFont(xDisplay, countFontID);
2592 //    appData.font = FindFont(appData.font, fontPxlSize);
2593
2594     xdb = XtDatabase(xDisplay);
2595     XrmPutStringResource(&xdb, "*font", appData.font);
2596
2597     /*
2598      * Detect if there are not enough colors available and adapt.
2599      */
2600     if (DefaultDepth(xDisplay, xScreen) <= 2) {
2601       appData.monoMode = True;
2602     }
2603
2604     if (!appData.monoMode) {
2605         vFrom.addr = (caddr_t) appData.lightSquareColor;
2606         vFrom.size = strlen(appData.lightSquareColor);
2607         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2608         if (vTo.addr == NULL) {
2609           appData.monoMode = True;
2610           forceMono = True;
2611         } else {
2612           lightSquareColor = *(Pixel *) vTo.addr;
2613         }
2614     }
2615     if (!appData.monoMode) {
2616         vFrom.addr = (caddr_t) appData.darkSquareColor;
2617         vFrom.size = strlen(appData.darkSquareColor);
2618         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2619         if (vTo.addr == NULL) {
2620           appData.monoMode = True;
2621           forceMono = True;
2622         } else {
2623           darkSquareColor = *(Pixel *) vTo.addr;
2624         }
2625     }
2626     if (!appData.monoMode) {
2627         vFrom.addr = (caddr_t) appData.whitePieceColor;
2628         vFrom.size = strlen(appData.whitePieceColor);
2629         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2630         if (vTo.addr == NULL) {
2631           appData.monoMode = True;
2632           forceMono = True;
2633         } else {
2634           whitePieceColor = *(Pixel *) vTo.addr;
2635         }
2636     }
2637     if (!appData.monoMode) {
2638         vFrom.addr = (caddr_t) appData.blackPieceColor;
2639         vFrom.size = strlen(appData.blackPieceColor);
2640         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2641         if (vTo.addr == NULL) {
2642           appData.monoMode = True;
2643           forceMono = True;
2644         } else {
2645           blackPieceColor = *(Pixel *) vTo.addr;
2646         }
2647     }
2648
2649     if (!appData.monoMode) {
2650         vFrom.addr = (caddr_t) appData.highlightSquareColor;
2651         vFrom.size = strlen(appData.highlightSquareColor);
2652         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2653         if (vTo.addr == NULL) {
2654           appData.monoMode = True;
2655           forceMono = True;
2656         } else {
2657           highlightSquareColor = *(Pixel *) vTo.addr;
2658         }
2659     }
2660
2661     if (!appData.monoMode) {
2662         vFrom.addr = (caddr_t) appData.premoveHighlightColor;
2663         vFrom.size = strlen(appData.premoveHighlightColor);
2664         XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2665         if (vTo.addr == NULL) {
2666           appData.monoMode = True;
2667           forceMono = True;
2668         } else {
2669           premoveHighlightColor = *(Pixel *) vTo.addr;
2670         }
2671     }
2672
2673     if (forceMono) {
2674       fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
2675               programName);
2676       
2677       if (appData.bitmapDirectory == NULL ||
2678               appData.bitmapDirectory[0] == NULLCHAR)
2679             appData.bitmapDirectory = DEF_BITMAP_DIR;
2680     }
2681
2682     if (appData.lowTimeWarning && !appData.monoMode) {
2683       vFrom.addr = (caddr_t) appData.lowTimeWarningColor;
2684       vFrom.size = strlen(appData.lowTimeWarningColor);
2685       XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2686       if (vTo.addr == NULL) 
2687                 appData.monoMode = True;
2688       else
2689                 lowTimeWarningColor = *(Pixel *) vTo.addr;
2690     }
2691
2692     if (appData.monoMode && appData.debugMode) {
2693         fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
2694                 (unsigned long) XWhitePixel(xDisplay, xScreen),
2695                 (unsigned long) XBlackPixel(xDisplay, xScreen));
2696     }
2697
2698     if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
2699         parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
2700         parse_cpair(ColorChannel1, appData.colorChannel1) < 0  ||
2701         parse_cpair(ColorChannel, appData.colorChannel) < 0  ||
2702         parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
2703         parse_cpair(ColorTell, appData.colorTell) < 0 ||
2704         parse_cpair(ColorChallenge, appData.colorChallenge) < 0  ||
2705         parse_cpair(ColorRequest, appData.colorRequest) < 0  ||
2706         parse_cpair(ColorSeek, appData.colorSeek) < 0  ||
2707         parse_cpair(ColorNormal, appData.colorNormal) < 0)
2708       {
2709           if (appData.colorize) {
2710               fprintf(stderr,
2711                       _("%s: can't parse color names; disabling colorization\n"),
2712                       programName);
2713           }
2714           appData.colorize = FALSE;
2715       }
2716     textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
2717     textColors[ColorNone].attr = 0;
2718
2719     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
2720
2721     /*
2722      * widget hierarchy
2723      */
2724     if (tinyLayout) {
2725         layoutName = "tinyLayout";
2726     } else if (smallLayout) {
2727         layoutName = "smallLayout";
2728     } else {
2729         layoutName = "normalLayout";
2730     }
2731     /* Outer layoutWidget is there only to provide a name for use in
2732        resources that depend on the layout style */
2733     layoutWidget =
2734       XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
2735                             layoutArgs, XtNumber(layoutArgs));
2736     formWidget =
2737       XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
2738                             formArgs, XtNumber(formArgs));
2739     XtSetArg(args[0], XtNdefaultDistance, &sep);
2740     XtGetValues(formWidget, args, 1);
2741
2742     j = 0;
2743     widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
2744     XtSetArg(args[0], XtNtop,    XtChainTop);
2745     XtSetArg(args[1], XtNbottom, XtChainTop);
2746     XtSetValues(menuBarWidget, args, 2);
2747
2748     widgetList[j++] = whiteTimerWidget =
2749       XtCreateWidget("whiteTime", labelWidgetClass,
2750                      formWidget, timerArgs, XtNumber(timerArgs));
2751     XtSetArg(args[0], XtNfont, clockFontStruct);
2752     XtSetArg(args[1], XtNtop,    XtChainTop);
2753     XtSetArg(args[2], XtNbottom, XtChainTop);
2754     XtSetValues(whiteTimerWidget, args, 3);
2755
2756     widgetList[j++] = blackTimerWidget =
2757       XtCreateWidget("blackTime", labelWidgetClass,
2758                      formWidget, timerArgs, XtNumber(timerArgs));
2759     XtSetArg(args[0], XtNfont, clockFontStruct);
2760     XtSetArg(args[1], XtNtop,    XtChainTop);
2761     XtSetArg(args[2], XtNbottom, XtChainTop);
2762     XtSetValues(blackTimerWidget, args, 3);
2763
2764     if (appData.titleInWindow) {
2765         widgetList[j++] = titleWidget =
2766           XtCreateWidget("title", labelWidgetClass, formWidget,
2767                          titleArgs, XtNumber(titleArgs));
2768         XtSetArg(args[0], XtNtop,    XtChainTop);
2769         XtSetArg(args[1], XtNbottom, XtChainTop);
2770         XtSetValues(titleWidget, args, 2);
2771     }
2772
2773     if (appData.showButtonBar) {
2774       widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
2775       XtSetArg(args[0], XtNleft,  XtChainRight); // [HGM] glue to right window edge
2776       XtSetArg(args[1], XtNright, XtChainRight); //       for good run-time sizing
2777       XtSetArg(args[2], XtNtop,    XtChainTop);
2778       XtSetArg(args[3], XtNbottom, XtChainTop);
2779       XtSetValues(buttonBarWidget, args, 4);
2780     }
2781
2782     widgetList[j++] = messageWidget =
2783       XtCreateWidget("message", labelWidgetClass, formWidget,
2784                      messageArgs, XtNumber(messageArgs));
2785     XtSetArg(args[0], XtNtop,    XtChainTop);
2786     XtSetArg(args[1], XtNbottom, XtChainTop);
2787     XtSetValues(messageWidget, args, 2);
2788
2789     widgetList[j++] = boardWidget =
2790       XtCreateWidget("board", widgetClass, formWidget, boardArgs,
2791                      XtNumber(boardArgs));
2792
2793     XtManageChildren(widgetList, j);
2794
2795     timerWidth = (boardWidth - sep) / 2;
2796     XtSetArg(args[0], XtNwidth, timerWidth);
2797     XtSetValues(whiteTimerWidget, args, 1);
2798     XtSetValues(blackTimerWidget, args, 1);
2799
2800     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
2801     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
2802     XtGetValues(whiteTimerWidget, args, 2);
2803
2804     if (appData.showButtonBar) {
2805       XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
2806       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
2807       XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
2808     }
2809
2810     /*
2811      * formWidget uses these constraints but they are stored
2812      * in the children.
2813      */
2814     i = 0;
2815     XtSetArg(args[i], XtNfromHoriz, 0); i++;
2816     XtSetValues(menuBarWidget, args, i);
2817     if (appData.titleInWindow) {
2818         if (smallLayout) {
2819             i = 0;
2820             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2821             XtSetValues(whiteTimerWidget, args, i);
2822             i = 0;
2823             XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2824             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2825             XtSetValues(blackTimerWidget, args, i);
2826             i = 0;
2827             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2828             XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
2829             XtSetValues(titleWidget, args, i);
2830             i = 0;
2831             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2832             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2833             XtSetValues(messageWidget, args, i);
2834             if (appData.showButtonBar) {
2835               i = 0;
2836               XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2837               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2838               XtSetValues(buttonBarWidget, args, i);
2839             }
2840         } else {
2841             i = 0;
2842             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2843             XtSetValues(whiteTimerWidget, args, i);
2844             i = 0;
2845             XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2846             XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2847             XtSetValues(blackTimerWidget, args, i);
2848             i = 0;
2849             XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
2850             XtSetValues(titleWidget, args, i);
2851             i = 0;
2852             XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2853             XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2854             XtSetValues(messageWidget, args, i);
2855             if (appData.showButtonBar) {
2856               i = 0;
2857               XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2858               XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2859               XtSetValues(buttonBarWidget, args, i);
2860             }
2861         }
2862     } else {
2863         i = 0;
2864         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2865         XtSetValues(whiteTimerWidget, args, i);
2866         i = 0;
2867         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2868         XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2869         XtSetValues(blackTimerWidget, args, i);
2870         i = 0;
2871         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2872         XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2873         XtSetValues(messageWidget, args, i);
2874         if (appData.showButtonBar) {
2875           i = 0;
2876           XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2877           XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2878           XtSetValues(buttonBarWidget, args, i);
2879         }
2880     }
2881     i = 0;
2882     XtSetArg(args[0], XtNfromVert, messageWidget);
2883     XtSetArg(args[1], XtNtop,    XtChainTop);
2884     XtSetArg(args[2], XtNbottom, XtChainBottom);
2885     XtSetArg(args[3], XtNleft,   XtChainLeft);
2886     XtSetArg(args[4], XtNright,  XtChainRight);
2887     XtSetValues(boardWidget, args, 5);
2888
2889     XtRealizeWidget(shellWidget);
2890
2891     /*
2892      * Correct the width of the message and title widgets.
2893      * It is not known why some systems need the extra fudge term.
2894      * The value "2" is probably larger than needed.
2895      */
2896     XawFormDoLayout(formWidget, False);
2897
2898 #define WIDTH_FUDGE 2
2899     i = 0;
2900     XtSetArg(args[i], XtNborderWidth, &bor);  i++;
2901     XtSetArg(args[i], XtNheight, &h);  i++;
2902     XtGetValues(messageWidget, args, i);
2903     if (appData.showButtonBar) {
2904       i = 0;
2905       XtSetArg(args[i], XtNwidth, &w);  i++;
2906       XtGetValues(buttonBarWidget, args, i);
2907       w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2908     } else {
2909       w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
2910     }
2911
2912     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2913     if (gres != XtGeometryYes && appData.debugMode) {
2914       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2915               programName, gres, w, h, wr, hr);
2916     }
2917
2918     /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
2919     /* The size used for the child widget in layout lags one resize behind
2920        its true size, so we resize a second time, 1 pixel smaller.  Yeech! */
2921     w--;
2922     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2923     if (gres != XtGeometryYes && appData.debugMode) {
2924       fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2925               programName, gres, w, h, wr, hr);
2926     }
2927     /* !! end hack */
2928     XtSetArg(args[0], XtNleft,  XtChainLeft);  // [HGM] glue ends for good run-time sizing
2929     XtSetArg(args[1], XtNright, XtChainRight);
2930     XtSetValues(messageWidget, args, 2);
2931
2932     if (appData.titleInWindow) {
2933         i = 0;
2934         XtSetArg(args[i], XtNborderWidth, &bor); i++;
2935         XtSetArg(args[i], XtNheight, &h);  i++;
2936         XtGetValues(titleWidget, args, i);
2937         if (smallLayout) {
2938             w = boardWidth - 2*bor;
2939         } else {
2940             XtSetArg(args[0], XtNwidth, &w);
2941             XtGetValues(menuBarWidget, args, 1);
2942             w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2943         }
2944
2945         gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2946         if (gres != XtGeometryYes && appData.debugMode) {
2947             fprintf(stderr,
2948                     _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2949                     programName, gres, w, h, wr, hr);
2950         }
2951     }
2952     XawFormDoLayout(formWidget, True);
2953
2954     xBoardWindow = XtWindow(boardWidget);
2955
2956     // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
2957     //       not need to go into InitDrawingSizes().
2958 #endif
2959
2960     /*
2961      * Create X checkmark bitmap and initialize option menu checks.
2962      */
2963     ReadBitmap(&xMarkPixmap, "checkmark.bm",
2964                checkmark_bits, checkmark_width, checkmark_height);
2965     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
2966     if (appData.alwaysPromoteToQueen) {
2967         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
2968                     args, 1);
2969     }
2970     if (appData.animateDragging) {
2971         XtSetValues(XtNameToWidget(menuBarWidget,
2972                                    "menuOptions.Animate Dragging"),
2973                     args, 1);
2974     }
2975     if (appData.animate) {
2976         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
2977                     args, 1);
2978     }
2979     if (appData.autoComment) {
2980         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
2981                     args, 1);
2982     }
2983     if (appData.autoCallFlag) {
2984         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
2985                     args, 1);
2986     }
2987     if (appData.autoFlipView) {
2988         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
2989                     args, 1);
2990     }
2991     if (appData.autoObserve) {
2992         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
2993                     args, 1);
2994     }
2995     if (appData.autoRaiseBoard) {
2996         XtSetValues(XtNameToWidget(menuBarWidget,
2997                                    "menuOptions.Auto Raise Board"), args, 1);
2998     }
2999     if (appData.autoSaveGames) {
3000         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
3001                     args, 1);
3002     }
3003     if (appData.saveGameFile[0] != NULLCHAR) {
3004         /* Can't turn this off from menu */
3005         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
3006                     args, 1);
3007         XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
3008                        False);
3009
3010     }
3011     if (appData.blindfold) {
3012         XtSetValues(XtNameToWidget(menuBarWidget,
3013                                    "menuOptions.Blindfold"), args, 1);
3014     }
3015     if (appData.flashCount > 0) {
3016         XtSetValues(XtNameToWidget(menuBarWidget,
3017                                    "menuOptions.Flash Moves"),
3018                     args, 1);
3019     }
3020     if (appData.getMoveList) {
3021         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
3022                     args, 1);
3023     }
3024 #if HIGHDRAG
3025     if (appData.highlightDragging) {
3026         XtSetValues(XtNameToWidget(menuBarWidget,
3027                                    "menuOptions.Highlight Dragging"),
3028                     args, 1);
3029     }
3030 #endif
3031     if (appData.highlightLastMove) {
3032         XtSetValues(XtNameToWidget(menuBarWidget,
3033                                    "menuOptions.Highlight Last Move"),
3034                     args, 1);
3035     }
3036     if (appData.icsAlarm) {
3037         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
3038                     args, 1);
3039     }
3040     if (appData.ringBellAfterMoves) {
3041         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
3042                     args, 1);
3043     }
3044     if (appData.oldSaveStyle) {
3045         XtSetValues(XtNameToWidget(menuBarWidget,
3046                                    "menuOptions.Old Save Style"), args, 1);
3047     }
3048     if (appData.periodicUpdates) {
3049         XtSetValues(XtNameToWidget(menuBarWidget,
3050                                    "menuOptions.Periodic Updates"), args, 1);
3051     }
3052     if (appData.ponderNextMove) {
3053         XtSetValues(XtNameToWidget(menuBarWidget,
3054                                    "menuOptions.Ponder Next Move"), args, 1);
3055     }
3056     if (appData.popupExitMessage) {
3057         XtSetValues(XtNameToWidget(menuBarWidget,
3058                                    "menuOptions.Popup Exit Message"), args, 1);
3059     }
3060     if (appData.popupMoveErrors) {
3061         XtSetValues(XtNameToWidget(menuBarWidget,
3062                                    "menuOptions.Popup Move Errors"), args, 1);
3063     }
3064     if (appData.premove) {
3065         XtSetValues(XtNameToWidget(menuBarWidget,
3066                                    "menuOptions.Premove"), args, 1);
3067     }
3068     if (appData.quietPlay) {
3069         XtSetValues(XtNameToWidget(menuBarWidget,
3070                                    "menuOptions.Quiet Play"), args, 1);
3071     }
3072     if (appData.showCoords) {
3073         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
3074                     args, 1);
3075     }
3076     if (appData.hideThinkingFromHuman) {
3077         XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
3078                     args, 1);
3079     }
3080     if (appData.testLegality) {
3081         XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
3082                     args, 1);
3083     }
3084
3085     /*
3086      * Create an icon.
3087      */
3088     ReadBitmap(&wIconPixmap, "icon_white.bm",
3089                icon_white_bits, icon_white_width, icon_white_height);
3090     ReadBitmap(&bIconPixmap, "icon_black.bm",
3091                icon_black_bits, icon_black_width, icon_black_height);
3092     iconPixmap = wIconPixmap;
3093     i = 0;
3094     XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
3095     XtSetValues(shellWidget, args, i);
3096
3097     /*
3098      * Create a cursor for the board widget.
3099      */
3100     window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
3101     XChangeWindowAttributes(xDisplay, xBoardWindow,
3102                             CWCursor, &window_attributes);
3103
3104     /*
3105      * Inhibit shell resizing.
3106      */
3107     shellArgs[0].value = (XtArgVal) &w;
3108     shellArgs[1].value = (XtArgVal) &h;
3109     XtGetValues(shellWidget, shellArgs, 2);
3110     shellArgs[4].value = shellArgs[2].value = w;
3111     shellArgs[5].value = shellArgs[3].value = h;
3112     XtSetValues(shellWidget, &shellArgs[2], 4);
3113     marginW =  w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
3114     marginH =  h - boardHeight;
3115
3116     CatchDeleteWindow(shellWidget, "QuitProc");
3117
3118     CreateGCs();
3119     CreateGrid();
3120 #if HAVE_LIBXPM
3121     if (appData.bitmapDirectory[0] != NULLCHAR) {
3122       CreatePieces();
3123     } else {
3124       CreateXPMPieces();
3125     }
3126 #else
3127     CreateXIMPieces();
3128     /* Create regular pieces */
3129     if (!useImages) CreatePieces();
3130 #endif
3131
3132     CreatePieceMenus();
3133
3134     if (appData.animate || appData.animateDragging)
3135       CreateAnimVars();
3136
3137     XtAugmentTranslations(formWidget,
3138                           XtParseTranslationTable(globalTranslations));
3139     XtAugmentTranslations(boardWidget,
3140                           XtParseTranslationTable(boardTranslations));
3141     XtAugmentTranslations(whiteTimerWidget,
3142                           XtParseTranslationTable(whiteTranslations));
3143     XtAugmentTranslations(blackTimerWidget,
3144                           XtParseTranslationTable(blackTranslations));
3145
3146     /* Why is the following needed on some versions of X instead
3147      * of a translation? */
3148     XtAddEventHandler(boardWidget, ExposureMask, False,
3149                       (XtEventHandler) EventProc, NULL);
3150     /* end why */
3151
3152     InitBackEnd2();
3153
3154     if (errorExitStatus == -1) {
3155         if (appData.icsActive) {
3156             /* We now wait until we see "login:" from the ICS before
3157                sending the logon script (problems with timestamp otherwise) */
3158             /*ICSInitScript();*/
3159             if (appData.icsInputBox) ICSInputBoxPopUp();
3160         }
3161
3162         signal(SIGINT, IntSigHandler);
3163         signal(SIGTERM, IntSigHandler);
3164         if (*appData.cmailGameName != NULLCHAR) {
3165             signal(SIGUSR1, CmailSigHandler);
3166         }
3167     }
3168     gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes()
3169     InitPosition(TRUE);
3170
3171     XtAppMainLoop(appContext);
3172     if (appData.debugMode) fclose(debugFP); // [DM] debug
3173     return 0;
3174 }
3175
3176 void
3177 ShutDownFrontEnd()
3178 {
3179     if (appData.icsActive && oldICSInteractionTitle != NULL) {
3180         DisplayIcsInteractionTitle(oldICSInteractionTitle);
3181     }
3182     unlink(gameCopyFilename);
3183     unlink(gamePasteFilename);
3184 }
3185
3186 RETSIGTYPE
3187 IntSigHandler(sig)
3188      int sig;
3189 {
3190     ExitEvent(sig);
3191 }
3192
3193 RETSIGTYPE
3194 CmailSigHandler(sig)
3195      int sig;
3196 {
3197     int dummy = 0;
3198     int error;
3199
3200     signal(SIGUSR1, SIG_IGN);   /* suspend handler     */
3201
3202     /* Activate call-back function CmailSigHandlerCallBack()             */
3203     OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
3204
3205     signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
3206 }
3207
3208 void
3209 CmailSigHandlerCallBack(isr, closure, message, count, error)
3210      InputSourceRef isr;
3211      VOIDSTAR closure;
3212      char *message;
3213      int count;
3214      int error;
3215 {
3216     BoardToTop();
3217     ReloadCmailMsgEvent(TRUE);  /* Reload cmail msg  */
3218 }
3219 /**** end signal code ****/
3220
3221
3222 void
3223 ICSInitScript()
3224 {
3225     FILE *f;
3226     char buf[MSG_SIZ];
3227     char *p;
3228
3229     f = fopen(appData.icsLogon, "r");
3230     if (f == NULL) {
3231         p = getenv("HOME");
3232         if (p != NULL) {
3233             strcpy(buf, p);
3234             strcat(buf, "/");
3235             strcat(buf, appData.icsLogon);
3236             f = fopen(buf, "r");
3237         }
3238     }
3239     if (f != NULL)
3240       ProcessICSInitScript(f);
3241 }
3242
3243 void
3244 ResetFrontEnd()
3245 {
3246     CommentPopDown();
3247     EditCommentPopDown();
3248     TagsPopDown();
3249     return;
3250 }
3251
3252 typedef struct {
3253     char *name;
3254     Boolean value;
3255 } Enables;
3256
3257 void
3258 SetMenuEnables(enab)
3259      Enables *enab;
3260 {
3261   Widget w;
3262   if (!menuBarWidget) return;
3263   while (enab->name != NULL) {
3264     w = XtNameToWidget(menuBarWidget, enab->name);
3265     if (w == NULL) {
3266       DisplayError(enab->name, 0);
3267     } else {
3268       XtSetSensitive(w, enab->value);
3269     }
3270     enab++;
3271   }
3272 }
3273
3274 Enables icsEnables[] = {
3275     { "menuFile.Mail Move", False },
3276     { "menuFile.Reload CMail Message", False },
3277     { "menuMode.Machine Black", False },
3278     { "menuMode.Machine White", False },
3279     { "menuMode.Analysis Mode", False },
3280     { "menuMode.Analyze File", False },
3281     { "menuMode.Two Machines", False },
3282 #ifndef ZIPPY
3283     { "menuHelp.Hint", False },
3284     { "menuHelp.Book", False },
3285     { "menuStep.Move Now", False },
3286     { "menuOptions.Periodic Updates", False },
3287     { "menuOptions.Hide Thinking", False },
3288     { "menuOptions.Ponder Next Move", False },
3289 #endif
3290     { NULL, False }
3291 };
3292
3293 Enables ncpEnables[] = {
3294     { "menuFile.Mail Move", False },
3295     { "menuFile.Reload CMail Message", False },
3296     { "menuMode.Machine White", False },
3297     { "menuMode.Machine Black", False },
3298     { "menuMode.Analysis Mode", False },
3299     { "menuMode.Analyze File", False },
3300     { "menuMode.Two Machines", False },
3301     { "menuMode.ICS Client", False },
3302     { "menuMode.ICS Input Box", False },
3303     { "Action", False },
3304     { "menuStep.Revert", False },
3305     { "menuStep.Move Now", False },
3306     { "menuStep.Retract Move", False },
3307     { "menuOptions.Auto Comment", False },
3308     { "menuOptions.Auto Flag", False },
3309     { "menuOptions.Auto Flip View", False },
3310     { "menuOptions.Auto Observe", False },
3311     { "menuOptions.Auto Raise Board", False },
3312     { "menuOptions.Get Move List", False },
3313     { "menuOptions.ICS Alarm", False },
3314     { "menuOptions.Move Sound", False },
3315     { "menuOptions.Quiet Play", False },
3316     { "menuOptions.Hide Thinking", False },
3317     { "menuOptions.Periodic Updates", False },
3318     { "menuOptions.Ponder Next Move", False },
3319     { "menuHelp.Hint", False },
3320     { "menuHelp.Book", False },
3321     { NULL, False }
3322 };
3323
3324 Enables gnuEnables[] = {
3325     { "menuMode.ICS Client", False },
3326     { "menuMode.ICS Input Box", False },
3327     { "menuAction.Accept", False },
3328     { "menuAction.Decline", False },
3329     { "menuAction.Rematch", False },
3330     { "menuAction.Adjourn", False },
3331     { "menuAction.Stop Examining", False },
3332     { "menuAction.Stop Observing", False },
3333     { "menuStep.Revert", False },
3334     { "menuOptions.Auto Comment", False },
3335     { "menuOptions.Auto Observe", False },
3336     { "menuOptions.Auto Raise Board", False },
3337     { "menuOptions.Get Move List", False },
3338     { "menuOptions.Premove", False },
3339     { "menuOptions.Quiet Play", False },
3340
3341     /* The next two options rely on SetCmailMode being called *after*    */
3342     /* SetGNUMode so that when GNU is being used to give hints these     */
3343     /* menu options are still available                                  */
3344
3345     { "menuFile.Mail Move", False },
3346     { "menuFile.Reload CMail Message", False },
3347     { NULL, False }
3348 };
3349
3350 Enables cmailEnables[] = {
3351     { "Action", True },
3352     { "menuAction.Call Flag", False },
3353     { "menuAction.Draw", True },
3354     { "menuAction.Adjourn", False },
3355     { "menuAction.Abort", False },
3356     { "menuAction.Stop Observing", False },
3357     { "menuAction.Stop Examining", False },
3358     { "menuFile.Mail Move", True },
3359     { "menuFile.Reload CMail Message", True },
3360     { NULL, False }
3361 };
3362
3363 Enables trainingOnEnables[] = {
3364   { "menuMode.Edit Comment", False },
3365   { "menuMode.Pause", False },
3366   { "menuStep.Forward", False },
3367   { "menuStep.Backward", False },
3368   { "menuStep.Forward to End", False },
3369   { "menuStep.Back to Start", False },
3370   { "menuStep.Move Now", False },
3371   { "menuStep.Truncate Game", False },
3372   { NULL, False }
3373 };
3374
3375 Enables trainingOffEnables[] = {
3376   { "menuMode.Edit Comment", True },
3377   { "menuMode.Pause", True },
3378   { "menuStep.Forward", True },
3379   { "menuStep.Backward", True },
3380   { "menuStep.Forward to End", True },
3381   { "menuStep.Back to Start", True },
3382   { "menuStep.Move Now", True },
3383   { "menuStep.Truncate Game", True },
3384   { NULL, False }
3385 };
3386
3387 Enables machineThinkingEnables[] = {
3388   { "menuFile.Load Game", False },
3389   { "menuFile.Load Next Game", False },
3390   { "menuFile.Load Previous Game", False },
3391   { "menuFile.Reload Same Game", False },
3392   { "menuFile.Paste Game", False },
3393   { "menuFile.Load Position", False },
3394   { "menuFile.Load Next Position", False },
3395   { "menuFile.Load Previous Position", False },
3396   { "menuFile.Reload Same Position", False },
3397   { "menuFile.Paste Position", False },
3398   { "menuMode.Machine White", False },
3399   { "menuMode.Machine Black", False },
3400   { "menuMode.Two Machines", False },
3401   { "menuStep.Retract Move", False },
3402   { NULL, False }
3403 };
3404
3405 Enables userThinkingEnables[] = {
3406   { "menuFile.Load Game", True },
3407   { "menuFile.Load Next Game", True },
3408   { "menuFile.Load Previous Game", True },
3409   { "menuFile.Reload Same Game", True },
3410   { "menuFile.Paste Game", True },
3411   { "menuFile.Load Position", True },
3412   { "menuFile.Load Next Position", True },
3413   { "menuFile.Load Previous Position", True },
3414   { "menuFile.Reload Same Position", True },
3415   { "menuFile.Paste Position", True },
3416   { "menuMode.Machine White", True },
3417   { "menuMode.Machine Black", True },
3418   { "menuMode.Two Machines", True },
3419   { "menuStep.Retract Move", True },
3420   { NULL, False }
3421 };
3422
3423 void SetICSMode()
3424 {
3425   SetMenuEnables(icsEnables);
3426
3427 #ifdef ZIPPY
3428   if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
3429      XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
3430 #endif
3431 }
3432
3433 void
3434 SetNCPMode()
3435 {
3436   SetMenuEnables(ncpEnables);
3437 }
3438
3439 void
3440 SetGNUMode()
3441 {
3442   SetMenuEnables(gnuEnables);
3443 }
3444
3445 void
3446 SetCmailMode()
3447 {
3448   SetMenuEnables(cmailEnables);
3449 }
3450
3451 void
3452 SetTrainingModeOn()
3453 {
3454   SetMenuEnables(trainingOnEnables);
3455   if (appData.showButtonBar) {
3456     XtSetSensitive(buttonBarWidget, False);
3457   }
3458   CommentPopDown();
3459 }
3460
3461 void
3462 SetTrainingModeOff()
3463 {
3464   SetMenuEnables(trainingOffEnables);
3465   if (appData.showButtonBar) {
3466     XtSetSensitive(buttonBarWidget, True);
3467   }
3468 }
3469
3470 void
3471 SetUserThinkingEnables()
3472 {
3473   if (appData.noChessProgram) return;
3474   SetMenuEnables(userThinkingEnables);
3475 }
3476
3477 void
3478 SetMachineThinkingEnables()
3479 {
3480   if (appData.noChessProgram) return;
3481   SetMenuEnables(machineThinkingEnables);
3482   switch (gameMode) {
3483   case MachinePlaysBlack:
3484   case MachinePlaysWhite:
3485   case TwoMachinesPlay:
3486     XtSetSensitive(XtNameToWidget(menuBarWidget,
3487                                   ModeToWidgetName(gameMode)), True);
3488     break;
3489   default:
3490     break;
3491   }
3492 }
3493
3494 #define Abs(n) ((n)<0 ? -(n) : (n))
3495
3496 /*
3497  * Find a font that matches "pattern" that is as close as
3498  * possible to the targetPxlSize.  Prefer fonts that are k
3499  * pixels smaller to fonts that are k pixels larger.  The
3500  * pattern must be in the X Consortium standard format,
3501  * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
3502  * The return value should be freed with XtFree when no
3503  * longer needed.
3504  */
3505 char *FindFont(pattern, targetPxlSize)
3506      char *pattern;
3507      int targetPxlSize;
3508 {
3509     char **fonts, *p, *best, *scalable, *scalableTail;
3510     int i, j, nfonts, minerr, err, pxlSize;
3511
3512 #ifdef ENABLE_NLS
3513     char **missing_list;
3514     int missing_count;
3515     char *def_string, *base_fnt_lst, strInt[3];
3516     XFontSet fntSet;
3517     XFontStruct **fnt_list;
3518
3519     base_fnt_lst = calloc(1, strlen(pattern) + 3);
3520     sprintf(strInt, "%d", targetPxlSize);
3521     p = strstr(pattern, "--");
3522     strncpy(base_fnt_lst, pattern, p - pattern + 2);
3523     strcat(base_fnt_lst, strInt);
3524     strcat(base_fnt_lst, strchr(p + 2, '-'));
3525
3526     if ((fntSet = XCreateFontSet(xDisplay,
3527                                  base_fnt_lst,
3528                                  &missing_list,
3529                                  &missing_count,
3530                                  &def_string)) == NULL) {
3531
3532        fprintf(stderr, _("Unable to create font set.\n"));
3533        exit (2);
3534     }
3535
3536     nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
3537 #else
3538     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
3539     if (nfonts < 1) {
3540         fprintf(stderr, _("%s: no fonts match pattern %s\n"),
3541                 programName, pattern);
3542         exit(2);
3543     }
3544 #endif
3545
3546     best = fonts[0];
3547     scalable = NULL;
3548     minerr = 999999;
3549     for (i=0; i<nfonts; i++) {
3550         j = 0;
3551         p = fonts[i];
3552         if (*p != '-') continue;
3553         while (j < 7) {
3554             if (*p == NULLCHAR) break;
3555             if (*p++ == '-') j++;
3556         }
3557         if (j < 7) continue;
3558         pxlSize = atoi(p);
3559         if (pxlSize == 0) {
3560             scalable = fonts[i];
3561             scalableTail = p;
3562         } else {
3563             err = pxlSize - targetPxlSize;
3564             if (Abs(err) < Abs(minerr) ||
3565                 (minerr > 0 && err < 0 && -err == minerr)) {
3566                 best = fonts[i];
3567                 minerr = err;
3568             }
3569         }
3570     }
3571     if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
3572         /* If the error is too big and there is a scalable font,
3573            use the scalable font. */
3574         int headlen = scalableTail - scalable;
3575         p = (char *) XtMalloc(strlen(scalable) + 10);
3576         while (isdigit(*scalableTail)) scalableTail++;
3577         sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
3578     } else {
3579         p = (char *) XtMalloc(strlen(best) + 1);
3580         strcpy(p, best);
3581     }
3582     if (appData.debugMode) {
3583         fprintf(debugFP, _("resolved %s at pixel size %d\n  to %s\n"),
3584                 pattern, targetPxlSize, p);
3585     }
3586 #ifdef ENABLE_NLS
3587     if (missing_count > 0)
3588        XFreeStringList(missing_list);
3589     XFreeFontSet(xDisplay, fntSet);
3590 #else
3591      XFreeFontNames(fonts);
3592 #endif
3593     return p;
3594 }
3595
3596 void CreateGCs()
3597 {
3598     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
3599       | GCBackground | GCFunction | GCPlaneMask;
3600     XGCValues gc_values;
3601     GC copyInvertedGC;
3602
3603     gc_values.plane_mask = AllPlanes;
3604     gc_values.line_width = lineGap;
3605     gc_values.line_style = LineSolid;
3606     gc_values.function = GXcopy;
3607
3608     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3609     gc_values.background = XBlackPixel(xDisplay, xScreen);
3610     lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3611
3612     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3613     gc_values.background = XWhitePixel(xDisplay, xScreen);
3614     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
3615     XSetFont(xDisplay, coordGC, coordFontID);
3616
3617     // [HGM] make font for holdings counts (white on black0
3618     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3619     gc_values.background = XBlackPixel(xDisplay, xScreen);
3620     countGC = XtGetGC(shellWidget, value_mask, &gc_values);
3621     XSetFont(xDisplay, countGC, countFontID);
3622
3623     if (appData.monoMode) {
3624         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3625         gc_values.background = XWhitePixel(xDisplay, xScreen);
3626         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3627
3628         gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3629         gc_values.background = XBlackPixel(xDisplay, xScreen);
3630         lightSquareGC = wbPieceGC
3631           = XtGetGC(shellWidget, value_mask, &gc_values);
3632
3633         gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3634         gc_values.background = XWhitePixel(xDisplay, xScreen);
3635         darkSquareGC = bwPieceGC
3636           = XtGetGC(shellWidget, value_mask, &gc_values);
3637
3638         if (DefaultDepth(xDisplay, xScreen) == 1) {
3639             /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
3640             gc_values.function = GXcopyInverted;
3641             copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
3642             gc_values.function = GXcopy;
3643             if (XBlackPixel(xDisplay, xScreen) == 1) {
3644                 bwPieceGC = darkSquareGC;
3645                 wbPieceGC = copyInvertedGC;
3646             } else {
3647                 bwPieceGC = copyInvertedGC;
3648                 wbPieceGC = lightSquareGC;
3649             }
3650         }
3651     } else {
3652         gc_values.foreground = highlightSquareColor;
3653         gc_values.background = highlightSquareColor;
3654         highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3655
3656         gc_values.foreground = premoveHighlightColor;
3657         gc_values.background = premoveHighlightColor;
3658         prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3659
3660         gc_values.foreground = lightSquareColor;
3661         gc_values.background = darkSquareColor;
3662         lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3663
3664         gc_values.foreground = darkSquareColor;
3665         gc_values.background = lightSquareColor;
3666         darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3667
3668         gc_values.foreground = jailSquareColor;
3669         gc_values.background = jailSquareColor;
3670         jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3671
3672         gc_values.foreground = whitePieceColor;
3673         gc_values.background = darkSquareColor;
3674         wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3675
3676         gc_values.foreground = whitePieceColor;
3677         gc_values.background = lightSquareColor;
3678         wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3679
3680         gc_values.foreground = whitePieceColor;
3681         gc_values.background = jailSquareColor;
3682         wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3683
3684         gc_values.foreground = blackPieceColor;
3685         gc_values.background = darkSquareColor;
3686         bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3687
3688         gc_values.foreground = blackPieceColor;
3689         gc_values.background = lightSquareColor;
3690         blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3691
3692         gc_values.foreground = blackPieceColor;
3693         gc_values.background = jailSquareColor;
3694         bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3695     }
3696 }
3697
3698 void loadXIM(xim, xmask, filename, dest, mask)
3699      XImage *xim;
3700      XImage *xmask;
3701      char *filename;
3702      Pixmap *dest;
3703      Pixmap *mask;
3704 {
3705     int x, y, w, h, p;
3706     FILE *fp;
3707     Pixmap temp;
3708     XGCValues   values;
3709     GC maskGC;
3710
3711     fp = fopen(filename, "rb");
3712     if (!fp) {
3713         fprintf(stderr, _("%s: error loading XIM!\n"), programName);
3714         exit(1);
3715     }
3716
3717     w = fgetc(fp);
3718     h = fgetc(fp);
3719
3720     for (y=0; y<h; ++y) {
3721         for (x=0; x<h; ++x) {
3722             p = fgetc(fp);
3723
3724             switch (p) {
3725               case 0:
3726                 XPutPixel(xim, x, y, blackPieceColor);
3727                 if (xmask)
3728                   XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
3729                 break;
3730               case 1:
3731                 XPutPixel(xim, x, y, darkSquareColor);
3732                 if (xmask)
3733                   XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
3734                 break;
3735               case 2:
3736                 XPutPixel(xim, x, y, whitePieceColor);
3737                 if (xmask)
3738                   XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
3739                 break;
3740               case 3:
3741                 XPutPixel(xim, x, y, lightSquareColor);
3742                 if (xmask)
3743                   XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
3744                 break;
3745             }
3746         }
3747     }
3748
3749     /* create Pixmap of piece */
3750     *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
3751                           w, h, xim->depth);
3752     XPutImage(xDisplay, *dest, lightSquareGC, xim,
3753               0, 0, 0, 0, w, h);
3754
3755     /* create Pixmap of clipmask
3756        Note: We assume the white/black pieces have the same
3757              outline, so we make only 6 masks. This is okay
3758              since the XPM clipmask routines do the same. */
3759     if (xmask) {
3760       temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
3761                             w, h, xim->depth);
3762       XPutImage(xDisplay, temp, lightSquareGC, xmask,
3763               0, 0, 0, 0, w, h);
3764
3765       /* now create the 1-bit version */
3766       *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
3767                           w, h, 1);
3768
3769       values.foreground = 1;
3770       values.background = 0;
3771
3772       /* Don't use XtGetGC, not read only */
3773       maskGC = XCreateGC(xDisplay, *mask,
3774                     GCForeground | GCBackground, &values);
3775       XCopyPlane(xDisplay, temp, *mask, maskGC,
3776                   0, 0, squareSize, squareSize, 0, 0, 1);
3777       XFreePixmap(xDisplay, temp);
3778     }
3779 }
3780
3781
3782 char pieceBitmapNames[] = "pnbrqfeacwmohijgdvlsukpnsl";
3783
3784 void CreateXIMPieces()
3785 {
3786     int piece, kind;
3787     char buf[MSG_SIZ];
3788     u_int ss;
3789     static char *ximkind[] = { "ll", "ld", "dl", "dd" };
3790     XImage *ximtemp;
3791
3792     ss = squareSize;
3793
3794     /* The XSynchronize calls were copied from CreatePieces.
3795        Not sure if needed, but can't hurt */
3796     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
3797                                      buffering bug */
3798
3799     /* temp needed by loadXIM() */
3800     ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3801                  0, 0, ss, ss, AllPlanes, XYPixmap);
3802
3803     if (strlen(appData.pixmapDirectory) == 0) {
3804       useImages = 0;
3805     } else {
3806         useImages = 1;
3807         if (appData.monoMode) {
3808           DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
3809                             0, 2);
3810           ExitEvent(2);
3811         }
3812         fprintf(stderr, _("\nLoading XIMs...\n"));
3813         /* Load pieces */
3814         for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
3815             fprintf(stderr, "%d", piece+1);
3816             for (kind=0; kind<4; kind++) {
3817                 fprintf(stderr, ".");
3818                 snprintf(buf, sizeof(buf), "%s/%s%c%s%u.xim",
3819                         ExpandPathName(appData.pixmapDirectory),
3820                         piece <= (int) WhiteKing ? "" : "w",
3821                         pieceBitmapNames[piece],
3822                         ximkind[kind], ss);
3823                 ximPieceBitmap[kind][piece] =
3824                   XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3825                             0, 0, ss, ss, AllPlanes, XYPixmap);
3826                 if (appData.debugMode)
3827                   fprintf(stderr, _("(File:%s:) "), buf);
3828                 loadXIM(ximPieceBitmap[kind][piece],
3829                         ximtemp, buf,
3830                         &(xpmPieceBitmap2[kind][piece]),
3831                         &(ximMaskPm2[piece]));
3832                 if(piece <= (int)WhiteKing)
3833                     xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
3834             }
3835             fprintf(stderr," ");
3836         }
3837         /* Load light and dark squares */
3838         /* If the LSQ and DSQ pieces don't exist, we will
3839            draw them with solid squares. */
3840         snprintf(buf,sizeof(buf), "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
3841         if (access(buf, 0) != 0) {
3842             useImageSqs = 0;
3843         } else {
3844             useImageSqs = 1;
3845             fprintf(stderr, _("light square "));
3846             ximLightSquare=
3847               XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3848                         0, 0, ss, ss, AllPlanes, XYPixmap);
3849             if (appData.debugMode)
3850               fprintf(stderr, _("(File:%s:) "), buf);
3851
3852             loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
3853             fprintf(stderr, _("dark square "));
3854             snprintf(buf,sizeof(buf), "%s/dsq%u.xim",
3855                     ExpandPathName(appData.pixmapDirectory), ss);
3856             if (appData.debugMode)
3857               fprintf(stderr, _("(File:%s:) "), buf);
3858             ximDarkSquare=
3859               XGetImage(xDisplay, DefaultRootWindow(xDisplay),
3860                         0, 0, ss, ss, AllPlanes, XYPixmap);
3861             loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
3862             xpmJailSquare = xpmLightSquare;
3863         }
3864         fprintf(stderr, _("Done.\n"));
3865     }
3866     XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
3867 }
3868
3869 #if HAVE_LIBXPM
3870 void CreateXPMPieces()
3871 {
3872     int piece, kind, r;
3873     char buf[MSG_SIZ];
3874     u_int ss = squareSize;
3875     XpmAttributes attr;
3876     static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
3877     XpmColorSymbol symbols[4];
3878
3879 #if 0
3880     /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
3881     if (appData.debugMode) {
3882         fprintf(stderr, "XPM Library Version: %d.%d%c\n",
3883                 XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
3884     }
3885 #endif
3886
3887     /* The XSynchronize calls were copied from CreatePieces.
3888        Not sure if needed, but can't hurt */
3889     XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
3890
3891     /* Setup translations so piece colors match square colors */
3892     symbols[0].name = "light_piece";
3893     symbols[0].value = appData.whitePieceColor;
3894     symbols[1].name = "dark_piece";
3895     symbols[1].value = appData.blackPieceColor;
3896     symbols[2].name = "light_square";
3897     symbols[2].value = appData.lightSquareColor;
3898     symbols[3].name = "dark_square";
3899     symbols[3].value = appData.darkSquareColor;
3900
3901     attr.valuemask = XpmColorSymbols;
3902     attr.colorsymbols = symbols;
3903     attr.numsymbols = 4;
3904
3905     if (appData.monoMode) {
3906       DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
3907                         0, 2);
3908       ExitEvent(2);
3909     }
3910     if (strlen(appData.pixmapDirectory) == 0) {
3911         XpmPieces* pieces = builtInXpms;
3912         useImages = 1;
3913         /* Load pieces */
3914         while (pieces->size != squareSize && pieces->size) pieces++;
3915         if (!pieces->size) {
3916           fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
3917           exit(1);
3918         }
3919         for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
3920             for (kind=0; kind<4; kind++) {
3921
3922                 if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
3923                                                pieces->xpm[piece][kind],
3924                                                &(xpmPieceBitmap2[kind][piece]),
3925                                                NULL, &attr)) != 0) {
3926                   fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
3927                           r, buf);
3928                   exit(1);
3929                 }
3930                 if(piece <= (int) WhiteKing)
3931                     xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
3932             }
3933         }
3934         useImageSqs = 0;
3935         xpmJailSquare = xpmLightSquare;
3936     } else {
3937         useImages = 1;
3938
3939         fprintf(stderr, _("\nLoading XPMs...\n"));
3940
3941         /* Load pieces */
3942         for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
3943             fprintf(stderr, "%d ", piece+1);
3944             for (kind=0; kind<4; kind++) {
3945               snprintf(buf, sizeof(buf), "%s/%s%c%s%u.xpm",
3946                         ExpandPathName(appData.pixmapDirectory),
3947                         piece > (int) WhiteKing ? "w" : "",
3948                         pieceBitmapNames[piece],
3949                         xpmkind[kind], ss);
3950                 if (appData.debugMode) {
3951                     fprintf(stderr, _("(File:%s:) "), buf);
3952                 }
3953                 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
3954                                            &(xpmPieceBitmap2[kind][piece]),
3955                                            NULL, &attr)) != 0) {
3956                     fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
3957                             r, buf);
3958                     exit(1);
3959                 }
3960                 if(piece <= (int) WhiteKing) 
3961                     xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
3962             }
3963         }
3964         /* Load light and dark squares */
3965         /* If the LSQ and DSQ pieces don't exist, we will
3966            draw them with solid squares. */
3967         fprintf(stderr, _("light square "));
3968         snprintf(buf, sizeof(buf), "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
3969         if (access(buf, 0) != 0) {
3970             useImageSqs = 0;
3971         } else {
3972             useImageSqs = 1;
3973             if (appData.debugMode)
3974               fprintf(stderr, _("(File:%s:) "), buf);
3975
3976             if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
3977                                        &xpmLightSquare, NULL, &attr)) != 0) {
3978                 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
3979                 exit(1);
3980             }
3981             fprintf(stderr, _("dark square "));
3982             snprintf(buf, sizeof(buf), "%s/dsq%u.xpm",
3983                     ExpandPathName(appData.pixmapDirectory), ss);
3984             if (appData.debugMode) {
3985                 fprintf(stderr, _("(File:%s:) "), buf);
3986             }
3987             if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
3988                                        &xpmDarkSquare, NULL, &attr)) != 0) {
3989                 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
3990                 exit(1);
3991             }
3992         }
3993         xpmJailSquare = xpmLightSquare;
3994         fprintf(stderr, _("Done.\n"));
3995     }
3996     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
3997                                       buffering bug */
3998 }
3999 #endif /* HAVE_LIBXPM */
4000
4001 #if HAVE_LIBXPM
4002 /* No built-in bitmaps */
4003 void CreatePieces()
4004 {
4005     int piece, kind;
4006     char buf[MSG_SIZ];
4007     u_int ss = squareSize;
4008
4009     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
4010                                      buffering bug */
4011
4012     for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
4013         for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
4014             sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
4015                     pieceBitmapNames[piece],
4016                     ss, kind == SOLID ? 's' : 'o');
4017             ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss);
4018             if(piece <= (int)WhiteKing)
4019                 pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
4020         }
4021     }
4022
4023     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
4024                                       buffering bug */
4025 }
4026 #else
4027 /* With built-in bitmaps */
4028 void CreatePieces()
4029 {
4030     BuiltInBits* bib = builtInBits;
4031     int piece, kind;
4032     char buf[MSG_SIZ];
4033     u_int ss = squareSize;
4034
4035     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
4036                                      buffering bug */
4037
4038     while (bib->squareSize != ss && bib->squareSize != 0) bib++;
4039
4040     for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
4041         for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
4042             sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
4043                     pieceBitmapNames[piece],
4044                     ss, kind == SOLID ? 's' : 'o');
4045             ReadBitmap(&pieceBitmap2[kind][piece], buf,
4046                        bib->bits[kind][piece], ss, ss);
4047             if(piece <= (int)WhiteKing)
4048                 pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
4049         }
4050     }
4051
4052     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
4053                                       buffering bug */
4054 }
4055 #endif
4056
4057 void ReadBitmap(pm, name, bits, wreq, hreq)
4058      Pixmap *pm;
4059      String name;
4060      unsigned char bits[];
4061      u_int wreq, hreq;
4062 {
4063     int x_hot, y_hot;
4064     u_int w, h;
4065     int errcode;
4066     char msg[MSG_SIZ], fullname[MSG_SIZ];
4067
4068     if (*appData.bitmapDirectory != NULLCHAR) {
4069         strcpy(fullname, appData.bitmapDirectory);
4070         strcat(fullname, "/");
4071         strcat(fullname, name);
4072         errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
4073                                   &w, &h, pm, &x_hot, &y_hot);
4074     fprintf(stderr, "load %s\n", name);
4075         if (errcode != BitmapSuccess) {
4076             switch (errcode) {
4077               case BitmapOpenFailed:
4078                 snprintf(msg, sizeof(msg), _("Can't open bitmap file %s"), fullname);
4079                 break;
4080               case BitmapFileInvalid:
4081                 snprintf(msg, sizeof(msg), _("Invalid bitmap in file %s"), fullname);
4082                 break;
4083               case BitmapNoMemory:
4084                 snprintf(msg, sizeof(msg), _("Ran out of memory reading bitmap file %s"),
4085                         fullname);
4086                 break;
4087               default:
4088                 snprintf(msg, sizeof(msg), _("Unknown XReadBitmapFile error %d on file %s"),
4089                         errcode, fullname);
4090                 break;
4091             }
4092             fprintf(stderr, _("%s: %s...using built-in\n"),
4093                     programName, msg);
4094         } else if (w != wreq || h != hreq) {
4095