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