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