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