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
5 * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
\r
6 * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.
\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
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
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
28 * ------------------------------------------------------------------------
\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
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
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
48 * See the file ChangeLog for a revision history.
\r
57 #include <sys/types.h>
\r
58 #include <sys/stat.h>
\r
62 # if HAVE_SYS_SOCKET_H
\r
63 # include <sys/socket.h>
\r
64 # include <netinet/in.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
78 # include <stdlib.h>
\r
79 # include <string.h>
\r
80 #else /* not STDC_HEADERS */
\r
81 extern char *getenv();
\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
89 #if HAVE_SYS_FCNTL_H
\r
90 # include <sys/fcntl.h>
\r
91 #else /* not HAVE_SYS_FCNTL_H */
\r
94 # endif /* HAVE_FCNTL_H */
\r
95 #endif /* not HAVE_SYS_FCNTL_H */
\r
97 #if HAVE_SYS_SYSTEMINFO_H
\r
98 # include <sys/systeminfo.h>
\r
99 #endif /* HAVE_SYS_SYSTEMINFO_H */
\r
101 #if TIME_WITH_SYS_TIME
\r
102 # include <sys/time.h>
\r
105 # if HAVE_SYS_TIME_H
\r
106 # include <sys/time.h>
\r
113 # include <unistd.h>
\r
116 #if HAVE_SYS_WAIT_H
\r
117 # include <sys/wait.h>
\r
121 # include <dirent.h>
\r
122 # define NAMLEN(dirent) strlen((dirent)->d_name)
\r
123 # define HAVE_DIR_STRUCT
\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
131 # if HAVE_SYS_DIR_H
\r
132 # include <sys/dir.h>
\r
133 # define HAVE_DIR_STRUCT
\r
137 # define HAVE_DIR_STRUCT
\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
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
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
172 // [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
\r
173 #include "common.h"
\r
176 #include <X11/xpm.h>
\r
177 #include "pixmaps/pixmaps.h"
\r
178 #define IMAGE_EXT "xpm"
\r
180 #define IMAGE_EXT "xim"
\r
181 #include "bitmaps/bitmaps.h"
\r
184 #include "bitmaps/icon_white.bm"
\r
185 #include "bitmaps/icon_black.bm"
\r
186 #include "bitmaps/checkmark.bm"
\r
188 #include "frontend.h"
\r
189 #include "backend.h"
\r
191 #include "xboard.h"
\r
192 #include "childio.h"
\r
193 #include "xgamelist.h"
\r
194 #include "xhistory.h"
\r
195 #include "xedittags.h"
\r
196 #include "gettext.h"
\r
198 // must be moved to xengineoutput.h
\r
200 void EngineOutputProc P((Widget w, XEvent *event,
\r
201 String *prms, Cardinal *nprms));
\r
203 void EngineOutputPopDown();
\r
207 #ifndef HAVE_USLEEP
\r
208 #define HAVE_USLEEP
\r
210 #define usleep(t) _sleep2(((t)+500)/1000)
\r
214 # define _(s) gettext (s)
\r
215 # define N_(s) gettext_noop (s)
\r
231 int main P((int argc, char **argv));
\r
232 RETSIGTYPE CmailSigHandler P((int sig));
\r
233 RETSIGTYPE IntSigHandler P((int sig));
\r
234 void CreateGCs P((void));
\r
235 void CreateXIMPieces P((void));
\r
236 void CreateXPMPieces P((void));
\r
237 void CreatePieces P((void));
\r
238 void CreatePieceMenus P((void));
\r
239 Widget CreateMenuBar P((Menu *mb));
\r
240 Widget CreateButtonBar P ((MenuItem *mi));
\r
241 char *FindFont P((char *pattern, int targetPxlSize));
\r
242 void PieceMenuPopup P((Widget w, XEvent *event,
\r
243 String *params, Cardinal *num_params));
\r
244 static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
\r
245 static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
\r
246 void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
\r
247 u_int wreq, u_int hreq));
\r
248 void CreateGrid P((void));
\r
249 int EventToSquare P((int x, int limit));
\r
250 void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
\r
251 void EventProc P((Widget widget, caddr_t unused, XEvent *event));
\r
252 void HandleUserMove P((Widget w, XEvent *event,
\r
253 String *prms, Cardinal *nprms));
\r
254 void AnimateUserMove P((Widget w, XEvent * event,
\r
255 String * params, Cardinal * nParams));
\r
256 void WhiteClock P((Widget w, XEvent *event,
\r
257 String *prms, Cardinal *nprms));
\r
258 void BlackClock P((Widget w, XEvent *event,
\r
259 String *prms, Cardinal *nprms));
\r
260 void DrawPositionProc P((Widget w, XEvent *event,
\r
261 String *prms, Cardinal *nprms));
\r
262 void XDrawPosition P((Widget w, /*Boolean*/int repaint,
\r
264 void CommentPopUp P((char *title, char *label));
\r
265 void CommentPopDown P((void));
\r
266 void CommentCallback P((Widget w, XtPointer client_data,
\r
267 XtPointer call_data));
\r
268 void ICSInputBoxPopUp P((void));
\r
269 void ICSInputBoxPopDown P((void));
\r
270 void FileNamePopUp P((char *label, char *def,
\r
271 FileProc proc, char *openMode));
\r
272 void FileNamePopDown P((void));
\r
273 void FileNameCallback P((Widget w, XtPointer client_data,
\r
274 XtPointer call_data));
\r
275 void FileNameAction P((Widget w, XEvent *event,
\r
276 String *prms, Cardinal *nprms));
\r
277 void AskQuestionReplyAction P((Widget w, XEvent *event,
\r
278 String *prms, Cardinal *nprms));
\r
279 void AskQuestionProc P((Widget w, XEvent *event,
\r
280 String *prms, Cardinal *nprms));
\r
281 void AskQuestionPopDown P((void));
\r
282 void PromotionPopUp P((void));
\r
283 void PromotionPopDown P((void));
\r
284 void PromotionCallback P((Widget w, XtPointer client_data,
\r
285 XtPointer call_data));
\r
286 void EditCommentPopDown P((void));
\r
287 void EditCommentCallback P((Widget w, XtPointer client_data,
\r
288 XtPointer call_data));
\r
289 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
\r
290 void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
291 void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
292 void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
\r
294 void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
\r
296 void ReloadGameProc P((Widget w, XEvent *event, String *prms,
\r
298 void LoadPositionProc P((Widget w, XEvent *event,
\r
299 String *prms, Cardinal *nprms));
\r
300 void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
\r
302 void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
\r
304 void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
\r
306 void CopyPositionProc P((Widget w, XEvent *event, String *prms,
\r
308 void PastePositionProc P((Widget w, XEvent *event, String *prms,
\r
310 void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
311 void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
312 void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
313 void SavePositionProc P((Widget w, XEvent *event,
\r
314 String *prms, Cardinal *nprms));
\r
315 void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
316 void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
\r
318 void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
319 void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
320 void MachineBlackProc P((Widget w, XEvent *event, String *prms,
\r
322 void MachineWhiteProc P((Widget w, XEvent *event,
\r
323 String *prms, Cardinal *nprms));
\r
324 void AnalyzeModeProc P((Widget w, XEvent *event,
\r
325 String *prms, Cardinal *nprms));
\r
326 void AnalyzeFileProc P((Widget w, XEvent *event,
\r
327 String *prms, Cardinal *nprms));
\r
328 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
\r
330 void IcsClientProc P((Widget w, XEvent *event, String *prms,
\r
332 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
333 void EditPositionProc P((Widget w, XEvent *event,
\r
334 String *prms, Cardinal *nprms));
\r
335 void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
336 void EditCommentProc P((Widget w, XEvent *event,
\r
337 String *prms, Cardinal *nprms));
\r
338 void IcsInputBoxProc P((Widget w, XEvent *event,
\r
339 String *prms, Cardinal *nprms));
\r
340 void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
341 void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
342 void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
343 void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
344 void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
345 void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
346 void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
347 void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
348 void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
349 void StopObservingProc P((Widget w, XEvent *event, String *prms,
\r
351 void StopExaminingProc P((Widget w, XEvent *event, String *prms,
\r
353 void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
354 void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
355 void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
356 void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
357 void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
358 void TruncateGameProc P((Widget w, XEvent *event, String *prms,
\r
360 void RetractMoveProc P((Widget w, XEvent *event, String *prms,
\r
362 void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
363 void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
\r
365 void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
\r
367 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
\r
369 void AutocommProc P((Widget w, XEvent *event, String *prms,
\r
371 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
372 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
373 void AutobsProc P((Widget w, XEvent *event, String *prms,
\r
375 void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
376 void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
377 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
378 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
\r
380 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
381 void GetMoveListProc P((Widget w, XEvent *event, String *prms,
\r
383 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
\r
385 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
\r
387 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
388 void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
389 void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
\r
391 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
\r
393 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
\r
395 void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
\r
397 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
\r
399 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
400 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
401 void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
\r
403 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
\r
405 void HideThinkingProc P((Widget w, XEvent *event, String *prms,
\r
407 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
\r
409 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
410 void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
411 void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
412 void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
413 void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
414 void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
415 void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
416 void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
417 void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
418 void DisplayMove P((int moveNumber));
\r
419 void DisplayTitle P((char *title));
\r
420 void ICSInitScript P((void));
\r
421 int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
\r
422 void ErrorPopUp P((char *title, char *text, int modal));
\r
423 void ErrorPopDown P((void));
\r
424 static char *ExpandPathName P((char *path));
\r
425 static void CreateAnimVars P((void));
\r
426 static void DragPieceBegin P((int x, int y));
\r
427 static void DragPieceMove P((int x, int y));
\r
428 static void DragPieceEnd P((int x, int y));
\r
429 static void DrawDragPiece P((void));
\r
430 char *ModeToWidgetName P((GameMode mode));
\r
431 void EngineOutputUpdate( FrontEndProgramStats * stats );
\r
432 void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
433 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
434 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
435 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
436 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
437 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
438 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
439 void ShufflePopDown P(());
\r
440 void EnginePopDown P(());
\r
441 void UciPopDown P(());
\r
442 void TimeControlPopDown P(());
\r
443 void NewVariantPopDown P(());
\r
444 void SettingsPopDown P(());
\r
446 * XBoard depends on Xt R4 or higher
\r
448 int xtVersion = XtSpecificationRelease;
\r
452 Window xBoardWindow;
\r
453 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
\r
454 jailSquareColor, highlightSquareColor, premoveHighlightColor;
\r
455 GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
\r
456 bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
\r
457 wjPieceGC, bjPieceGC, prelineGC, countGC;
\r
458 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
\r
459 Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
\r
460 whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
\r
461 commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
\r
462 menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
\r
463 ICSInputShell, fileNameShell, askQuestionShell;
\r
464 XSegment gridSegments[(BOARD_SIZE + 1) * 2];
\r
465 XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
\r
466 Font clockFontID, coordFontID, countFontID;
\r
467 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
\r
468 XtAppContext appContext;
\r
470 char *oldICSInteractionTitle;
\r
473 char *fileOpenMode;
\r
474 char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
\r
476 Position commentX = -1, commentY = -1;
\r
477 Dimension commentW, commentH;
\r
479 int squareSize, smallLayout = 0, tinyLayout = 0,
\r
480 marginW, marginH, // [HGM] for run-time resizing
\r
481 fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
\r
482 ICSInputBoxUp = False, askQuestionUp = False,
\r
483 filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
\r
484 editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
\r
485 Pixel timerForegroundPixel, timerBackgroundPixel;
\r
486 Pixel buttonForegroundPixel, buttonBackgroundPixel;
\r
487 char *chessDir, *programName, *programVersion,
\r
488 *gameCopyFilename, *gamePasteFilename;
\r
492 Pixmap pieceBitmap[2][(int)BlackPawn];
\r
493 Pixmap xpmPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */
\r
494 Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
\r
495 int useImages, useImageSqs;
\r
496 XImage *ximPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */
\r
497 Pixmap ximMaskPm[(int)BlackPawn]; /* clipmasks, used for XIM pieces */
\r
498 XImage *ximLightSquare, *ximDarkSquare;
\r
501 #define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % (int)BlackPawn]
\r
502 #define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % (int)BlackPawn]
\r
504 #define White(piece) ((int)(piece) < (int)BlackPawn)
\r
506 /* Variables for doing smooth animation. This whole thing
\r
507 would be much easier if the board was double-buffered,
\r
508 but that would require a fairly major rewrite. */
\r
513 GC blitGC, pieceGC, outlineGC;
\r
514 XPoint startSquare, prevFrame, mouseDelta;
\r
517 Boolean dragActive;
\r
518 int startBoardX, startBoardY;
\r
521 /* There can be two pieces being animated at once: a player
\r
522 can begin dragging a piece before the remote opponent has moved. */
\r
524 static AnimState game, player;
\r
526 /* Bitmaps for use as masks when drawing XPM pieces.
\r
527 Need one for each black and white piece. */
\r
528 static Pixmap xpmMask[BlackKing + 1];
\r
530 /* This magic number is the number of intermediate frames used
\r
531 in each half of the animation. For short moves it's reduced
\r
532 by 1. The total number of frames will be factor * 2 + 1. */
\r
535 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
\r
537 MenuItem fileMenu[] = {
\r
538 {N_("New Game"), ResetProc},
\r
539 {N_("New Shuffle Game ..."), ShuffleMenuProc},
\r
540 {N_("New Variant ..."), NewVariantProc}, // [HGM] variant: not functional yet
\r
541 {"----", NothingProc},
\r
542 {N_("Load Game"), LoadGameProc},
\r
543 {N_("Load Next Game"), LoadNextGameProc},
\r
544 {N_("Load Previous Game"), LoadPrevGameProc},
\r
545 {N_("Reload Same Game"), ReloadGameProc},
\r
546 {N_("Save Game"), SaveGameProc},
\r
547 {"----", NothingProc},
\r
548 {N_("Copy Game"), CopyGameProc},
\r
549 {N_("Paste Game"), PasteGameProc},
\r
550 {"----", NothingProc},
\r
551 {N_("Load Position"), LoadPositionProc},
\r
552 {N_("Load Next Position"), LoadNextPositionProc},
\r
553 {N_("Load Previous Position"), LoadPrevPositionProc},
\r
554 {N_("Reload Same Position"), ReloadPositionProc},
\r
555 {N_("Save Position"), SavePositionProc},
\r
556 {"----", NothingProc},
\r
557 {N_("Copy Position"), CopyPositionProc},
\r
558 {N_("Paste Position"), PastePositionProc},
\r
559 {"----", NothingProc},
\r
560 {N_("Mail Move"), MailMoveProc},
\r
561 {N_("Reload CMail Message"), ReloadCmailMsgProc},
\r
562 {"----", NothingProc},
\r
563 {N_("Exit"), QuitProc},
\r
567 MenuItem modeMenu[] = {
\r
568 {N_("Machine White"), MachineWhiteProc},
\r
569 {N_("Machine Black"), MachineBlackProc},
\r
570 {N_("Two Machines"), TwoMachinesProc},
\r
571 {N_("Analysis Mode"), AnalyzeModeProc},
\r
572 {N_("Analyze File"), AnalyzeFileProc },
\r
573 {N_("ICS Client"), IcsClientProc},
\r
574 {N_("Edit Game"), EditGameProc},
\r
575 {N_("Edit Position"), EditPositionProc},
\r
576 {N_("Training"), TrainingProc},
\r
577 {"----", NothingProc},
\r
578 {N_("Show Engine Output"), EngineOutputProc},
\r
579 {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
\r
580 {N_("Show Game List"), ShowGameListProc},
\r
581 {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
\r
582 {"----", NothingProc},
\r
583 {N_("Edit Tags"), EditTagsProc},
\r
584 {N_("Edit Comment"), EditCommentProc},
\r
585 {N_("ICS Input Box"), IcsInputBoxProc},
\r
586 {N_("Pause"), PauseProc},
\r
590 MenuItem actionMenu[] = {
\r
591 {N_("Accept"), AcceptProc},
\r
592 {N_("Decline"), DeclineProc},
\r
593 {N_("Rematch"), RematchProc},
\r
594 {"----", NothingProc},
\r
595 {N_("Call Flag"), CallFlagProc},
\r
596 {N_("Draw"), DrawProc},
\r
597 {N_("Adjourn"), AdjournProc},
\r
598 {N_("Abort"), AbortProc},
\r
599 {N_("Resign"), ResignProc},
\r
600 {"----", NothingProc},
\r
601 {N_("Stop Observing"), StopObservingProc},
\r
602 {N_("Stop Examining"), StopExaminingProc},
\r
606 MenuItem stepMenu[] = {
\r
607 {N_("Backward"), BackwardProc},
\r
608 {N_("Forward"), ForwardProc},
\r
609 {N_("Back to Start"), ToStartProc},
\r
610 {N_("Forward to End"), ToEndProc},
\r
611 {N_("Revert"), RevertProc},
\r
612 {N_("Truncate Game"), TruncateGameProc},
\r
613 {"----", NothingProc},
\r
614 {N_("Move Now"), MoveNowProc},
\r
615 {N_("Retract Move"), RetractMoveProc},
\r
619 MenuItem optionsMenu[] = {
\r
620 {N_("Flip View"), FlipViewProc},
\r
621 {"----", NothingProc},
\r
622 {N_("Adjudications ..."), EngineMenuProc},
\r
623 {N_("General Settings ..."), UciMenuProc},
\r
624 {N_("Engine #1 Settings ..."), FirstSettingsProc},
\r
625 {N_("Engine #2 Settings ..."), SecondSettingsProc},
\r
626 {N_("Time Control ..."), TimeControlProc},
\r
627 {"----", NothingProc},
\r
628 {N_("Always Queen"), AlwaysQueenProc},
\r
629 {N_("Animate Dragging"), AnimateDraggingProc},
\r
630 {N_("Animate Moving"), AnimateMovingProc},
\r
631 {N_("Auto Comment"), AutocommProc},
\r
632 {N_("Auto Flag"), AutoflagProc},
\r
633 {N_("Auto Flip View"), AutoflipProc},
\r
634 {N_("Auto Observe"), AutobsProc},
\r
635 {N_("Auto Raise Board"), AutoraiseProc},
\r
636 {N_("Auto Save"), AutosaveProc},
\r
637 {N_("Blindfold"), BlindfoldProc},
\r
638 {N_("Flash Moves"), FlashMovesProc},
\r
639 {N_("Get Move List"), GetMoveListProc},
\r
641 {N_("Highlight Dragging"), HighlightDraggingProc},
\r
643 {N_("Highlight Last Move"), HighlightLastMoveProc},
\r
644 {N_("Move Sound"), MoveSoundProc},
\r
645 {N_("ICS Alarm"), IcsAlarmProc},
\r
646 {N_("Old Save Style"), OldSaveStyleProc},
\r
647 {N_("Periodic Updates"), PeriodicUpdatesProc},
\r
648 {N_("Ponder Next Move"), PonderNextMoveProc},
\r
649 {N_("Popup Exit Message"), PopupExitMessageProc},
\r
650 {N_("Popup Move Errors"), PopupMoveErrorsProc},
\r
651 {N_("Premove"), PremoveProc},
\r
652 {N_("Quiet Play"), QuietPlayProc},
\r
653 {N_("Show Coords"), ShowCoordsProc},
\r
654 {N_("Hide Thinking"), HideThinkingProc},
\r
655 {N_("Test Legality"), TestLegalityProc},
\r
659 MenuItem helpMenu[] = {
\r
660 {N_("Info XBoard"), InfoProc},
\r
661 {N_("Man XBoard"), ManProc},
\r
662 {"----", NothingProc},
\r
663 {N_("Hint"), HintProc},
\r
664 {N_("Book"), BookProc},
\r
665 {"----", NothingProc},
\r
666 {N_("About XBoard"), AboutProc},
\r
671 {N_("File"), fileMenu},
\r
672 {N_("Mode"), modeMenu},
\r
673 {N_("Action"), actionMenu},
\r
674 {N_("Step"), stepMenu},
\r
675 {N_("Options"), optionsMenu},
\r
676 {N_("Help"), helpMenu},
\r
680 #define PAUSE_BUTTON N_("P")
\r
681 MenuItem buttonBar[] = {
\r
682 {"<<", ToStartProc},
\r
683 {"<", BackwardProc},
\r
684 {PAUSE_BUTTON, PauseProc},
\r
685 {">", ForwardProc},
\r
690 #define PIECE_MENU_SIZE 11
\r
691 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
\r
692 { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
\r
693 N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
\r
694 { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
\r
695 N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
\r
697 /* must be in same order as PieceMenuStrings! */
\r
698 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
\r
699 { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
\r
700 WhiteRook, WhiteQueen, WhiteKing,
\r
701 (ChessSquare) 0, EmptySquare, ClearBoard },
\r
702 { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
\r
703 BlackRook, BlackQueen, BlackKing,
\r
704 (ChessSquare) 0, EmptySquare, ClearBoard },
\r
707 #define DROP_MENU_SIZE 6
\r
708 String dropMenuStrings[DROP_MENU_SIZE] = {
\r
709 "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
\r
711 /* must be in same order as PieceMenuStrings! */
\r
712 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
\r
713 (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
\r
714 WhiteRook, WhiteQueen
\r
722 DropMenuEnables dmEnables[] = {
\r
730 Arg shellArgs[] = {
\r
733 { XtNminWidth, 0 },
\r
734 { XtNminHeight, 0 },
\r
735 { XtNmaxWidth, 0 },
\r
736 { XtNmaxHeight, 0 }
\r
739 Arg layoutArgs[] = {
\r
740 { XtNborderWidth, 0 },
\r
741 { XtNdefaultDistance, 0 },
\r
745 { XtNborderWidth, 0 },
\r
746 { XtNresizable, (XtArgVal) True },
\r
749 Arg boardArgs[] = {
\r
750 { XtNborderWidth, 0 },
\r
755 Arg titleArgs[] = {
\r
756 { XtNjustify, (XtArgVal) XtJustifyRight },
\r
757 { XtNlabel, (XtArgVal) "..." },
\r
758 { XtNresizable, (XtArgVal) True },
\r
759 { XtNresize, (XtArgVal) False }
\r
762 Arg messageArgs[] = {
\r
763 { XtNjustify, (XtArgVal) XtJustifyLeft },
\r
764 { XtNlabel, (XtArgVal) "..." },
\r
765 { XtNresizable, (XtArgVal) True },
\r
766 { XtNresize, (XtArgVal) False }
\r
769 Arg timerArgs[] = {
\r
770 { XtNborderWidth, 0 },
\r
771 { XtNjustify, (XtArgVal) XtJustifyLeft }
\r
774 XtResource clientResources[] = {
\r
775 { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
\r
776 XtOffset(AppDataPtr, whitePieceColor), XtRString,
\r
777 WHITE_PIECE_COLOR },
\r
778 { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
\r
779 XtOffset(AppDataPtr, blackPieceColor), XtRString,
\r
780 BLACK_PIECE_COLOR },
\r
781 { "lightSquareColor", "lightSquareColor", XtRString,
\r
782 sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
\r
783 XtRString, LIGHT_SQUARE_COLOR },
\r
784 { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
\r
785 XtOffset(AppDataPtr, darkSquareColor), XtRString,
\r
786 DARK_SQUARE_COLOR },
\r
787 { "highlightSquareColor", "highlightSquareColor", XtRString,
\r
788 sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
\r
789 XtRString, HIGHLIGHT_SQUARE_COLOR },
\r
790 { "premoveHighlightColor", "premoveHighlightColor", XtRString,
\r
791 sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
\r
792 XtRString, PREMOVE_HIGHLIGHT_COLOR },
\r
793 { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
\r
794 XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
\r
795 (XtPointer) MOVES_PER_SESSION },
\r
796 { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
\r
797 XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
\r
798 (XtPointer) TIME_INCREMENT },
\r
799 { "initString", "initString", XtRString, sizeof(String),
\r
800 XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
\r
801 { "secondInitString", "secondInitString", XtRString, sizeof(String),
\r
802 XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
\r
803 { "firstComputerString", "firstComputerString", XtRString,
\r
804 sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
\r
806 { "secondComputerString", "secondComputerString", XtRString,
\r
807 sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
\r
809 { "firstChessProgram", "firstChessProgram", XtRString,
\r
810 sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
\r
811 XtRString, FIRST_CHESS_PROGRAM },
\r
812 { "secondChessProgram", "secondChessProgram", XtRString,
\r
813 sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
\r
814 XtRString, SECOND_CHESS_PROGRAM },
\r
815 { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
\r
816 sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
\r
817 XtRImmediate, (XtPointer) False },
\r
818 { "noChessProgram", "noChessProgram", XtRBoolean,
\r
819 sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
\r
820 XtRImmediate, (XtPointer) False },
\r
821 { "firstHost", "firstHost", XtRString, sizeof(String),
\r
822 XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
\r
823 { "secondHost", "secondHost", XtRString, sizeof(String),
\r
824 XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
\r
825 { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
\r
826 XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
\r
827 { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
\r
828 XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
\r
829 { "bitmapDirectory", "bitmapDirectory", XtRString,
\r
830 sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
\r
832 { "remoteShell", "remoteShell", XtRString, sizeof(String),
\r
833 XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
\r
834 { "remoteUser", "remoteUser", XtRString, sizeof(String),
\r
835 XtOffset(AppDataPtr, remoteUser), XtRString, "" },
\r
836 { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
\r
837 XtOffset(AppDataPtr, timeDelay), XtRString,
\r
838 (XtPointer) TIME_DELAY_QUOTE },
\r
839 { "timeControl", "timeControl", XtRString, sizeof(String),
\r
840 XtOffset(AppDataPtr, timeControl), XtRString,
\r
841 (XtPointer) TIME_CONTROL },
\r
842 { "internetChessServerMode", "internetChessServerMode",
\r
843 XtRBoolean, sizeof(Boolean),
\r
844 XtOffset(AppDataPtr, icsActive), XtRImmediate,
\r
845 (XtPointer) False },
\r
846 { "internetChessServerHost", "internetChessServerHost",
\r
847 XtRString, sizeof(String),
\r
848 XtOffset(AppDataPtr, icsHost),
\r
849 XtRString, (XtPointer) ICS_HOST },
\r
850 { "internetChessServerPort", "internetChessServerPort",
\r
851 XtRString, sizeof(String),
\r
852 XtOffset(AppDataPtr, icsPort), XtRString,
\r
853 (XtPointer) ICS_PORT },
\r
854 { "internetChessServerCommPort", "internetChessServerCommPort",
\r
855 XtRString, sizeof(String),
\r
856 XtOffset(AppDataPtr, icsCommPort), XtRString,
\r
858 { "internetChessServerLogonScript", "internetChessServerLogonScript",
\r
859 XtRString, sizeof(String),
\r
860 XtOffset(AppDataPtr, icsLogon), XtRString,
\r
862 { "internetChessServerHelper", "internetChessServerHelper",
\r
863 XtRString, sizeof(String),
\r
864 XtOffset(AppDataPtr, icsHelper), XtRString, "" },
\r
865 { "internetChessServerInputBox", "internetChessServerInputBox",
\r
866 XtRBoolean, sizeof(Boolean),
\r
867 XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
\r
868 (XtPointer) False },
\r
869 { "icsAlarm", "icsAlarm",
\r
870 XtRBoolean, sizeof(Boolean),
\r
871 XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
\r
872 (XtPointer) True },
\r
873 { "icsAlarmTime", "icsAlarmTime",
\r
874 XtRInt, sizeof(int),
\r
875 XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
\r
876 (XtPointer) 5000 },
\r
877 { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
\r
878 XtOffset(AppDataPtr, useTelnet), XtRImmediate,
\r
879 (XtPointer) False },
\r
880 { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
\r
881 XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
\r
882 { "gateway", "gateway", XtRString, sizeof(String),
\r
883 XtOffset(AppDataPtr, gateway), XtRString, "" },
\r
884 { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
\r
885 XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
\r
886 { "loadGameIndex", "loadGameIndex",
\r
887 XtRInt, sizeof(int),
\r
888 XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
\r
890 { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
\r
891 XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
\r
892 { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
\r
893 sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
\r
894 XtRImmediate, (XtPointer) True },
\r
895 { "autoSaveGames", "autoSaveGames", XtRBoolean,
\r
896 sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
\r
897 XtRImmediate, (XtPointer) False },
\r
898 { "blindfold", "blindfold", XtRBoolean,
\r
899 sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
\r
900 XtRImmediate, (XtPointer) False },
\r
901 { "loadPositionFile", "loadPositionFile", XtRString,
\r
902 sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
\r
904 { "loadPositionIndex", "loadPositionIndex",
\r
905 XtRInt, sizeof(int),
\r
906 XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
\r
908 { "savePositionFile", "savePositionFile", XtRString,
\r
909 sizeof(String), XtOffset(AppDataPtr, savePositionFile),
\r
911 { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
\r
912 XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
\r
913 { "matchGames", "matchGames", XtRInt, sizeof(int),
\r
914 XtOffset(AppDataPtr, matchGames), XtRImmediate,
\r
916 { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
\r
917 XtOffset(AppDataPtr, monoMode), XtRImmediate,
\r
918 (XtPointer) False },
\r
919 { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
\r
920 XtOffset(AppDataPtr, debugMode), XtRImmediate,
\r
921 (XtPointer) False },
\r
922 { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
\r
923 XtOffset(AppDataPtr, clockMode), XtRImmediate,
\r
924 (XtPointer) True },
\r
925 { "boardSize", "boardSize", XtRString, sizeof(String),
\r
926 XtOffset(AppDataPtr, boardSize), XtRString, "" },
\r
927 { "searchTime", "searchTime", XtRString, sizeof(String),
\r
928 XtOffset(AppDataPtr, searchTime), XtRString,
\r
930 { "searchDepth", "searchDepth", XtRInt, sizeof(int),
\r
931 XtOffset(AppDataPtr, searchDepth), XtRImmediate,
\r
933 { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
\r
934 XtOffset(AppDataPtr, showCoords), XtRImmediate,
\r
935 (XtPointer) False },
\r
936 { "showJail", "showJail", XtRInt, sizeof(int),
\r
937 XtOffset(AppDataPtr, showJail), XtRImmediate,
\r
939 { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
\r
940 XtOffset(AppDataPtr, showThinking), XtRImmediate,
\r
941 (XtPointer) True },
\r
942 { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
\r
943 XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
\r
944 (XtPointer) True },
\r
945 { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
\r
946 XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
\r
947 (XtPointer) True },
\r
948 { "clockFont", "clockFont", XtRString, sizeof(String),
\r
949 XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
\r
950 { "coordFont", "coordFont", XtRString, sizeof(String),
\r
951 XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
\r
952 { "font", "font", XtRString, sizeof(String),
\r
953 XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
\r
954 { "ringBellAfterMoves", "ringBellAfterMoves",
\r
955 XtRBoolean, sizeof(Boolean),
\r
956 XtOffset(AppDataPtr, ringBellAfterMoves),
\r
957 XtRImmediate, (XtPointer) False },
\r
958 { "autoCallFlag", "autoCallFlag", XtRBoolean,
\r
959 sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
\r
960 XtRImmediate, (XtPointer) False },
\r
961 { "autoFlipView", "autoFlipView", XtRBoolean,
\r
962 sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
\r
963 XtRImmediate, (XtPointer) True },
\r
964 { "autoObserve", "autoObserve", XtRBoolean,
\r
965 sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
\r
966 XtRImmediate, (XtPointer) False },
\r
967 { "autoComment", "autoComment", XtRBoolean,
\r
968 sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
\r
969 XtRImmediate, (XtPointer) False },
\r
970 { "getMoveList", "getMoveList", XtRBoolean,
\r
971 sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
\r
972 XtRImmediate, (XtPointer) True },
\r
974 { "highlightDragging", "highlightDragging", XtRBoolean,
\r
975 sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
\r
976 XtRImmediate, (XtPointer) False },
\r
978 { "highlightLastMove", "highlightLastMove", XtRBoolean,
\r
979 sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
\r
980 XtRImmediate, (XtPointer) False },
\r
981 { "premove", "premove", XtRBoolean,
\r
982 sizeof(Boolean), XtOffset(AppDataPtr, premove),
\r
983 XtRImmediate, (XtPointer) True },
\r
984 { "testLegality", "testLegality", XtRBoolean,
\r
985 sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
\r
986 XtRImmediate, (XtPointer) True },
\r
987 { "flipView", "flipView", XtRBoolean,
\r
988 sizeof(Boolean), XtOffset(AppDataPtr, flipView),
\r
989 XtRImmediate, (XtPointer) False },
\r
990 { "cmail", "cmailGameName", XtRString, sizeof(String),
\r
991 XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
\r
992 { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
\r
993 sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
\r
994 XtRImmediate, (XtPointer) False },
\r
995 { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
\r
996 sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
\r
997 XtRImmediate, (XtPointer) False },
\r
998 { "quietPlay", "quietPlay", XtRBoolean,
\r
999 sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
\r
1000 XtRImmediate, (XtPointer) False },
\r
1001 { "titleInWindow", "titleInWindow", XtRBoolean,
\r
1002 sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
\r
1003 XtRImmediate, (XtPointer) False },
\r
1004 { "localLineEditing", "localLineEditing", XtRBoolean,
\r
1005 sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
\r
1006 XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
\r
1008 { "zippyTalk", "zippyTalk", XtRBoolean,
\r
1009 sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
\r
1010 XtRImmediate, (XtPointer) ZIPPY_TALK },
\r
1011 { "zippyPlay", "zippyPlay", XtRBoolean,
\r
1012 sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
\r
1013 XtRImmediate, (XtPointer) ZIPPY_PLAY },
\r
1014 { "zippyLines", "zippyLines", XtRString, sizeof(String),
\r
1015 XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
\r
1016 { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
\r
1017 XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
\r
1018 { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
\r
1019 XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
\r
1020 { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
\r
1021 XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
\r
1022 { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
\r
1023 XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
\r
1024 ZIPPY_WRONG_PASSWORD },
\r
1025 { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
\r
1026 XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
\r
1027 { "zippyUseI", "zippyUseI", XtRBoolean,
\r
1028 sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
\r
1029 XtRImmediate, (XtPointer) ZIPPY_USE_I },
\r
1030 { "zippyBughouse", "zippyBughouse", XtRInt,
\r
1031 sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
\r
1032 XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
\r
1033 { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
\r
1034 sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
\r
1035 XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
\r
1036 { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
\r
1037 XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
\r
1038 { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
\r
1039 XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
\r
1040 { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
\r
1041 sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
\r
1042 XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
\r
1043 { "zippyAbort", "zippyAbort", XtRBoolean,
\r
1044 sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
\r
1045 XtRImmediate, (XtPointer) ZIPPY_ABORT },
\r
1046 { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
\r
1047 XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
\r
1048 { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
\r
1049 XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
\r
1050 (XtPointer) ZIPPY_MAX_GAMES },
\r
1051 { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
\r
1052 XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
\r
1053 (XtPointer) ZIPPY_REPLAY_TIMEOUT },
\r
1055 { "flashCount", "flashCount", XtRInt, sizeof(int),
\r
1056 XtOffset(AppDataPtr, flashCount), XtRImmediate,
\r
1057 (XtPointer) FLASH_COUNT },
\r
1058 { "flashRate", "flashRate", XtRInt, sizeof(int),
\r
1059 XtOffset(AppDataPtr, flashRate), XtRImmediate,
\r
1060 (XtPointer) FLASH_RATE },
\r
1061 { "pixmapDirectory", "pixmapDirectory", XtRString,
\r
1062 sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
\r
1064 { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
\r
1065 XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
\r
1066 (XtPointer) MS_LOGIN_DELAY },
\r
1067 { "colorizeMessages", "colorizeMessages", XtRBoolean,
\r
1068 sizeof(Boolean), XtOffset(AppDataPtr, colorize),
\r
1069 XtRImmediate, (XtPointer) False },
\r
1070 { "colorShout", "colorShout", XtRString,
\r
1071 sizeof(String), XtOffset(AppDataPtr, colorShout),
\r
1072 XtRString, COLOR_SHOUT },
\r
1073 { "colorSShout", "colorSShout", XtRString,
\r
1074 sizeof(String), XtOffset(AppDataPtr, colorSShout),
\r
1075 XtRString, COLOR_SSHOUT },
\r
1076 { "colorChannel1", "colorChannel1", XtRString,
\r
1077 sizeof(String), XtOffset(AppDataPtr, colorChannel1),
\r
1078 XtRString, COLOR_CHANNEL1 },
\r
1079 { "colorChannel", "colorChannel", XtRString,
\r
1080 sizeof(String), XtOffset(AppDataPtr, colorChannel),
\r
1081 XtRString, COLOR_CHANNEL },
\r
1082 { "colorKibitz", "colorKibitz", XtRString,
\r
1083 sizeof(String), XtOffset(AppDataPtr, colorKibitz),
\r
1084 XtRString, COLOR_KIBITZ },
\r
1085 { "colorTell", "colorTell", XtRString,
\r
1086 sizeof(String), XtOffset(AppDataPtr, colorTell),
\r
1087 XtRString, COLOR_TELL },
\r
1088 { "colorChallenge", "colorChallenge", XtRString,
\r
1089 sizeof(String), XtOffset(AppDataPtr, colorChallenge),
\r
1090 XtRString, COLOR_CHALLENGE },
\r
1091 { "colorRequest", "colorRequest", XtRString,
\r
1092 sizeof(String), XtOffset(AppDataPtr, colorRequest),
\r
1093 XtRString, COLOR_REQUEST },
\r
1094 { "colorSeek", "colorSeek", XtRString,
\r
1095 sizeof(String), XtOffset(AppDataPtr, colorSeek),
\r
1096 XtRString, COLOR_SEEK },
\r
1097 { "colorNormal", "colorNormal", XtRString,
\r
1098 sizeof(String), XtOffset(AppDataPtr, colorNormal),
\r
1099 XtRString, COLOR_NORMAL },
\r
1100 { "soundProgram", "soundProgram", XtRString,
\r
1101 sizeof(String), XtOffset(AppDataPtr, soundProgram),
\r
1102 XtRString, "play" },
\r
1103 { "soundShout", "soundShout", XtRString,
\r
1104 sizeof(String), XtOffset(AppDataPtr, soundShout),
\r
1106 { "soundSShout", "soundSShout", XtRString,
\r
1107 sizeof(String), XtOffset(AppDataPtr, soundSShout),
\r
1109 { "soundChannel1", "soundChannel1", XtRString,
\r
1110 sizeof(String), XtOffset(AppDataPtr, soundChannel1),
\r
1112 { "soundChannel", "soundChannel", XtRString,
\r
1113 sizeof(String), XtOffset(AppDataPtr, soundChannel),
\r
1115 { "soundKibitz", "soundKibitz", XtRString,
\r
1116 sizeof(String), XtOffset(AppDataPtr, soundKibitz),
\r
1118 { "soundTell", "soundTell", XtRString,
\r
1119 sizeof(String), XtOffset(AppDataPtr, soundTell),
\r
1121 { "soundChallenge", "soundChallenge", XtRString,
\r
1122 sizeof(String), XtOffset(AppDataPtr, soundChallenge),
\r
1124 { "soundRequest", "soundRequest", XtRString,
\r
1125 sizeof(String), XtOffset(AppDataPtr, soundRequest),
\r
1127 { "soundSeek", "soundSeek", XtRString,
\r
1128 sizeof(String), XtOffset(AppDataPtr, soundSeek),
\r
1130 { "soundMove", "soundMove", XtRString,
\r
1131 sizeof(String), XtOffset(AppDataPtr, soundMove),
\r
1133 { "soundIcsWin", "soundIcsWin", XtRString,
\r
1134 sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
\r
1136 { "soundIcsLoss", "soundIcsLoss", XtRString,
\r
1137 sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
\r
1139 { "soundIcsDraw", "soundIcsDraw", XtRString,
\r
1140 sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
\r
1142 { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
\r
1143 sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
\r
1145 { "soundIcsAlarm", "soundIcsAlarm", XtRString,
\r
1146 sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
\r
1148 { "reuseFirst", "reuseFirst", XtRBoolean,
\r
1149 sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
\r
1150 XtRImmediate, (XtPointer) True },
\r
1151 { "reuseSecond", "reuseSecond", XtRBoolean,
\r
1152 sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
\r
1153 XtRImmediate, (XtPointer) True },
\r
1154 { "animateDragging", "animateDragging", XtRBoolean,
\r
1155 sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
\r
1156 XtRImmediate, (XtPointer) True },
\r
1157 { "animateMoving", "animateMoving", XtRBoolean,
\r
1158 sizeof(Boolean), XtOffset(AppDataPtr, animate),
\r
1159 XtRImmediate, (XtPointer) True },
\r
1160 { "animateSpeed", "animateSpeed", XtRInt,
\r
1161 sizeof(int), XtOffset(AppDataPtr, animSpeed),
\r
1162 XtRImmediate, (XtPointer)10 },
\r
1163 { "popupExitMessage", "popupExitMessage", XtRBoolean,
\r
1164 sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
\r
1165 XtRImmediate, (XtPointer) True },
\r
1166 { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
\r
1167 sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
\r
1168 XtRImmediate, (XtPointer) False },
\r
1169 { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
\r
1170 sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
\r
1171 XtRImmediate, (XtPointer)4 },
\r
1172 { "initialMode", "initialMode", XtRString,
\r
1173 sizeof(String), XtOffset(AppDataPtr, initialMode),
\r
1174 XtRImmediate, (XtPointer) "" },
\r
1175 { "variant", "variant", XtRString,
\r
1176 sizeof(String), XtOffset(AppDataPtr, variant),
\r
1177 XtRImmediate, (XtPointer) "normal" },
\r
1178 { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
\r
1179 sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
\r
1180 XtRImmediate, (XtPointer)PROTOVER },
\r
1181 { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
\r
1182 sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
\r
1183 XtRImmediate, (XtPointer)PROTOVER },
\r
1184 { "showButtonBar", "showButtonBar", XtRBoolean,
\r
1185 sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
\r
1186 XtRImmediate, (XtPointer) True },
\r
1187 {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean, /* [DM] icsEngineAnalyze */
\r
1188 sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
\r
1189 XtRImmediate, (XtPointer) False },
\r
1190 { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
\r
1191 sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
\r
1192 XtRImmediate, (XtPointer) False },
\r
1193 { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
\r
1194 sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
\r
1195 XtRImmediate, (XtPointer) False },
\r
1196 { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
\r
1197 sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
\r
1198 XtRImmediate, (XtPointer) False },
\r
1199 { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
\r
1200 sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
\r
1201 XtRImmediate, (XtPointer) True },
\r
1202 { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
\r
1203 sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
\r
1204 XtRImmediate, (XtPointer) 0},
\r
1205 { "pgnEventHeader", "pgnEventHeader", XtRString,
\r
1206 sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
\r
1207 XtRImmediate, (XtPointer) "Computer Chess Game" },
\r
1208 { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
\r
1209 sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
\r
1210 XtRImmediate, (XtPointer) -1},
\r
1212 // [HGM] 4.3.xx options
\r
1213 { "boardWidth", "boardWidth", XtRInt,
\r
1214 sizeof(int), XtOffset(AppDataPtr, NrFiles),
\r
1215 XtRImmediate, (XtPointer) -1},
\r
1216 { "boardHeight", "boardHeight", XtRInt,
\r
1217 sizeof(int), XtOffset(AppDataPtr, NrRanks),
\r
1218 XtRImmediate, (XtPointer) -1},
\r
1219 { "matchPause", "matchPause", XtRInt,
\r
1220 sizeof(int), XtOffset(AppDataPtr, matchPause),
\r
1221 XtRImmediate, (XtPointer) 10000},
\r
1222 { "holdingsSize", "holdingsSize", XtRInt,
\r
1223 sizeof(int), XtOffset(AppDataPtr, holdingsSize),
\r
1224 XtRImmediate, (XtPointer) -1},
\r
1225 { "flipBlack", "flipBlack", XtRBoolean,
\r
1226 sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
\r
1227 XtRImmediate, (XtPointer) False},
\r
1228 { "allWhite", "allWhite", XtRBoolean,
\r
1229 sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
\r
1230 XtRImmediate, (XtPointer) False},
\r
1231 { "pieceToCharTable", "pieceToCharTable", XtRString,
\r
1232 sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
\r
1233 XtRImmediate, (XtPointer) 0},
\r
1234 { "alphaRank", "alphaRank", XtRBoolean,
\r
1235 sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
\r
1236 XtRImmediate, (XtPointer) False},
\r
1237 { "testClaims", "testClaims", XtRBoolean,
\r
1238 sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
\r
1239 XtRImmediate, (XtPointer) True},
\r
1240 { "checkMates", "checkMates", XtRBoolean,
\r
1241 sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
\r
1242 XtRImmediate, (XtPointer) True},
\r
1243 { "materialDraws", "materialDraws", XtRBoolean,
\r
1244 sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
\r
1245 XtRImmediate, (XtPointer) True},
\r
1246 { "trivialDraws", "trivialDraws", XtRBoolean,
\r
1247 sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
\r
1248 XtRImmediate, (XtPointer) False},
\r
1249 { "ruleMoves", "ruleMoves", XtRInt,
\r
1250 sizeof(int), XtOffset(AppDataPtr, ruleMoves),
\r
1251 XtRImmediate, (XtPointer) 51},
\r
1252 { "repeatsToDraw", "repeatsToDraw", XtRInt,
\r
1253 sizeof(int), XtOffset(AppDataPtr, drawRepeats),
\r
1254 XtRImmediate, (XtPointer) 6},
\r
1255 { "engineDebugOutput", "engineDebugOutput", XtRInt,
\r
1256 sizeof(int), XtOffset(AppDataPtr, engineComments),
\r
1257 XtRImmediate, (XtPointer) 1},
\r
1258 { "userName", "userName", XtRString,
\r
1259 sizeof(int), XtOffset(AppDataPtr, userName),
\r
1260 XtRImmediate, (XtPointer) 0},
\r
1261 { "autoKibitz", "autoKibitz", XtRBoolean,
\r
1262 sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
\r
1263 XtRImmediate, (XtPointer) False},
\r
1264 { "firstTimeOdds", "firstTimeOdds", XtRInt,
\r
1265 sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
\r
1266 XtRImmediate, (XtPointer) 1},
\r
1267 { "secondTimeOdds", "secondTimeOdds", XtRInt,
\r
1268 sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
\r
1269 XtRImmediate, (XtPointer) 1},
\r
1270 { "timeOddsMode", "timeOddsMode", XtRInt,
\r
1271 sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
\r
1272 XtRImmediate, (XtPointer) 0},
\r
1273 { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
\r
1274 sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
\r
1275 XtRImmediate, (XtPointer) 1},
\r
1276 { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
\r
1277 sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
\r
1278 XtRImmediate, (XtPointer) 1},
\r
1279 { "firstNPS", "firstNPS", XtRInt,
\r
1280 sizeof(int), XtOffset(AppDataPtr, firstNPS),
\r
1281 XtRImmediate, (XtPointer) -1},
\r
1282 { "secondNPS", "secondNPS", XtRInt,
\r
1283 sizeof(int), XtOffset(AppDataPtr, secondNPS),
\r
1284 XtRImmediate, (XtPointer) -1},
\r
1285 { "serverMoves", "serverMoves", XtRString,
\r
1286 sizeof(String), XtOffset(AppDataPtr, serverMovesName),
\r
1287 XtRImmediate, (XtPointer) 0},
\r
1288 { "serverPause", "serverPause", XtRInt,
\r
1289 sizeof(int), XtOffset(AppDataPtr, serverPause),
\r
1290 XtRImmediate, (XtPointer) 0},
\r
1291 { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
\r
1292 sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
\r
1293 XtRImmediate, (XtPointer) False},
\r
1294 { "userName", "userName", XtRString,
\r
1295 sizeof(String), XtOffset(AppDataPtr, userName),
\r
1296 XtRImmediate, (XtPointer) 0},
\r
1297 { "egtFormats", "egtFormats", XtRString,
\r
1298 sizeof(String), XtOffset(AppDataPtr, egtFormats),
\r
1299 XtRImmediate, (XtPointer) 0},
\r
1300 { "rewindIndex", "rewindIndex", XtRInt,
\r
1301 sizeof(int), XtOffset(AppDataPtr, rewindIndex),
\r
1302 XtRImmediate, (XtPointer) 0},
\r
1303 { "sameColorGames", "sameColorGames", XtRInt,
\r
1304 sizeof(int), XtOffset(AppDataPtr, sameColorGames),
\r
1305 XtRImmediate, (XtPointer) 0},
\r
1306 { "smpCores", "smpCores", XtRInt,
\r
1307 sizeof(int), XtOffset(AppDataPtr, smpCores),
\r
1308 XtRImmediate, (XtPointer) 1},
\r
1309 { "niceEngines", "niceEngines", XtRInt,
\r
1310 sizeof(int), XtOffset(AppDataPtr, niceEngines),
\r
1311 XtRImmediate, (XtPointer) 0},
\r
1313 // [HGM] Winboard_x UCI options
\r
1314 { "firstIsUCI", "firstIsUCI", XtRBoolean,
\r
1315 sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
\r
1316 XtRImmediate, (XtPointer) False},
\r
1317 { "secondIsUCI", "secondIsUCI", XtRBoolean,
\r
1318 sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
\r
1319 XtRImmediate, (XtPointer) False},
\r
1320 { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
\r
1321 sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
\r
1322 XtRImmediate, (XtPointer) True},
\r
1323 { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
\r
1324 sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
\r
1325 XtRImmediate, (XtPointer) True},
\r
1326 { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
\r
1327 sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
\r
1328 XtRImmediate, (XtPointer) False},
\r
1329 { "defaultHashSize", "defaultHashSize", XtRInt,
\r
1330 sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
\r
1331 XtRImmediate, (XtPointer) 64},
\r
1332 { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
\r
1333 sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
\r
1334 XtRImmediate, (XtPointer) 4},
\r
1335 { "polyglotDir", "polyglotDir", XtRString,
\r
1336 sizeof(String), XtOffset(AppDataPtr, polyglotDir),
\r
1337 XtRImmediate, (XtPointer) "." },
\r
1338 { "polyglotBook", "polyglotBook", XtRString,
\r
1339 sizeof(String), XtOffset(AppDataPtr, polyglotBook),
\r
1340 XtRImmediate, (XtPointer) "" },
\r
1341 { "defaultPathEGTB", "defaultPathEGTB", XtRString,
\r
1342 sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
\r
1343 XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
\r
1344 { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
\r
1345 sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
\r
1346 XtRImmediate, (XtPointer) 0},
\r
1347 { "delayAfterQuit", "delayAfterQuit", XtRInt,
\r
1348 sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
\r
1349 XtRImmediate, (XtPointer) 0},
\r
1350 { "nameOfDebugFile", "nameOfDebugFile", XtRString,
\r
1351 sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
\r
1352 XtRImmediate, (XtPointer) "xboard.debug"},
\r
1353 { "noGUI", "noGUI", XtRBoolean,
\r
1354 sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
\r
1355 XtRImmediate, (XtPointer) 0},
\r
1358 XrmOptionDescRec shellOptions[] = {
\r
1359 { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
\r
1360 { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
\r
1361 { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
\r
1362 { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
\r
1363 { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
\r
1364 { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
\r
1365 { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
\r
1366 { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
\r
1367 { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
\r
1368 { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
\r
1369 { "-initString", "initString", XrmoptionSepArg, NULL },
\r
1370 { "-firstInitString", "initString", XrmoptionSepArg, NULL },
\r
1371 { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
\r
1372 { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
\r
1373 { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
\r
1374 { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
\r
1375 { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
\r
1376 { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
\r
1377 { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
\r
1378 { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
\r
1379 { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
\r
1380 { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
\r
1381 { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
\r
1382 { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
\r
1383 { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
\r
1384 { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
\r
1385 { "-fh", "firstHost", XrmoptionSepArg, NULL },
\r
1386 { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
\r
1387 { "-sh", "secondHost", XrmoptionSepArg, NULL },
\r
1388 { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
\r
1389 { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
\r
1390 { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
\r
1391 { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
\r
1392 { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
\r
1393 { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
\r
1394 { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
\r
1395 { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
\r
1396 { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
\r
1397 { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
\r
1398 { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
\r
1399 { "-td", "timeDelay", XrmoptionSepArg, NULL },
\r
1400 { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
\r
1401 { "-tc", "timeControl", XrmoptionSepArg, NULL },
\r
1402 { "-internetChessServerMode", "internetChessServerMode",
\r
1403 XrmoptionSepArg, NULL },
\r
1404 { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
\r
1405 { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
\r
1406 { "-internetChessServerHost", "internetChessServerHost",
\r
1407 XrmoptionSepArg, NULL },
\r
1408 { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
\r
1409 { "-internetChessServerPort", "internetChessServerPort",
\r
1410 XrmoptionSepArg, NULL },
\r
1411 { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
\r
1412 { "-internetChessServerCommPort", "internetChessServerCommPort",
\r
1413 XrmoptionSepArg, NULL },
\r
1414 { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
\r
1415 { "-internetChessServerLogonScript", "internetChessServerLogonScript",
\r
1416 XrmoptionSepArg, NULL },
\r
1417 { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
\r
1418 { "-internetChessServerHelper", "internetChessServerHelper",
\r
1419 XrmoptionSepArg, NULL },
\r
1420 { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
\r
1421 { "-internetChessServerInputBox", "internetChessServerInputBox",
\r
1422 XrmoptionSepArg, NULL },
\r
1423 { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
\r
1424 { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
\r
1425 { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
\r
1426 { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
\r
1427 { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
\r
1428 { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
\r
1429 { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
\r
1430 { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
\r
1431 { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
\r
1432 { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
\r
1433 { "-gateway", "gateway", XrmoptionSepArg, NULL },
\r
1434 { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
\r
1435 { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
\r
1436 { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
\r
1437 { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
\r
1438 { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
\r
1439 { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
\r
1440 { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
\r
1441 { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
\r
1442 { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
\r
1443 { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
\r
1444 { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
\r
1445 { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
\r
1446 { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
\r
1447 { "-blind", "blindfold", XrmoptionNoArg, "True" },
\r
1448 { "-xblind", "blindfold", XrmoptionNoArg, "False" },
\r
1449 { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
\r
1450 { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
\r
1451 { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
\r
1452 { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
\r
1453 { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
\r
1454 { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
\r
1455 { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
\r
1456 { "-mm", "matchMode", XrmoptionNoArg, "True" },
\r
1457 { "-xmm", "matchMode", XrmoptionNoArg, "False" },
\r
1458 { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
\r
1459 { "-mg", "matchGames", XrmoptionSepArg, NULL },
\r
1460 { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
\r
1461 { "-mono", "monoMode", XrmoptionNoArg, "True" },
\r
1462 { "-xmono", "monoMode", XrmoptionNoArg, "False" },
\r
1463 { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
\r
1464 { "-debug", "debugMode", XrmoptionNoArg, "True" },
\r
1465 { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
\r
1466 { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
\r
1467 { "-clock", "clockMode", XrmoptionNoArg, "True" },
\r
1468 { "-xclock", "clockMode", XrmoptionNoArg, "False" },
\r
1469 { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
\r
1470 { "-size", "boardSize", XrmoptionSepArg, NULL },
\r
1471 { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
\r
1472 { "-st", "searchTime", XrmoptionSepArg, NULL },
\r
1473 { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
\r
1474 { "-depth", "searchDepth", XrmoptionSepArg, NULL },
\r
1475 { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
\r
1476 { "-coords", "showCoords", XrmoptionNoArg, "True" },
\r
1477 { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
\r
1479 { "-showJail", "showJail", XrmoptionSepArg, NULL },
\r
1480 { "-jail", "showJail", XrmoptionNoArg, "1" },
\r
1481 { "-sidejail", "showJail", XrmoptionNoArg, "2" },
\r
1482 { "-xjail", "showJail", XrmoptionNoArg, "0" },
\r
1484 { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
\r
1485 { "-thinking", "showThinking", XrmoptionNoArg, "True" },
\r
1486 { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
\r
1487 { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
\r
1488 { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
\r
1489 { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
\r
1490 { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
\r
1491 { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
\r
1492 { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
\r
1493 { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
\r
1494 { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
\r
1495 { "-font", "font", XrmoptionSepArg, NULL },
\r
1496 { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
\r
1497 { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
\r
1498 { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
\r
1499 { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
\r
1500 { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
\r
1501 { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
\r
1502 { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
\r
1503 { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
\r
1504 { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
\r
1505 { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
\r
1506 { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
\r
1507 { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
\r
1508 { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
\r
1509 { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
\r
1510 { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
\r
1511 { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
\r
1512 { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
\r
1513 { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
\r
1514 { "-moves", "getMoveList", XrmoptionNoArg, "True" },
\r
1515 { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
\r
1517 { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
\r
1518 { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
\r
1519 { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
\r
1521 { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
\r
1522 { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
\r
1523 { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
\r
1524 { "-premove", "premove", XrmoptionSepArg, NULL },
\r
1525 { "-pre", "premove", XrmoptionNoArg, "True" },
\r
1526 { "-xpre", "premove", XrmoptionNoArg, "False" },
\r
1527 { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
\r
1528 { "-legal", "testLegality", XrmoptionNoArg, "True" },
\r
1529 { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
\r
1530 { "-flipView", "flipView", XrmoptionSepArg, NULL },
\r
1531 { "-flip", "flipView", XrmoptionNoArg, "True" },
\r
1532 { "-xflip", "flipView", XrmoptionNoArg, "False" },
\r
1533 { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
\r
1534 { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
\r
1535 XrmoptionSepArg, NULL },
\r
1536 { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
\r
1537 { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
\r
1538 { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
\r
1539 { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
\r
1540 { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
\r
1541 { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
\r
1542 { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
\r
1543 { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
\r
1544 { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
\r
1545 { "-title", "titleInWindow", XrmoptionNoArg, "True" },
\r
1546 { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
\r
1548 { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
\r
1549 { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
\r
1550 { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
\r
1551 { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
\r
1552 { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
\r
1553 { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
\r
1554 { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
\r
1555 { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
\r
1556 { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
\r
1557 { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
\r
1558 { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
\r
1559 { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
\r
1560 { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
\r
1561 { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
\r
1562 { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
\r
1563 { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
\r
1564 { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
\r
1565 { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
\r
1566 { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
\r
1567 { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
\r
1568 { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
\r
1569 { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
\r
1570 { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
\r
1571 { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
\r
1572 { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
\r
1573 { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
\r
1574 { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
\r
1575 { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
\r
1576 { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
\r
1577 { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
\r
1579 { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
\r
1580 { "-flash", "flashCount", XrmoptionNoArg, "3" },
\r
1581 { "-xflash", "flashCount", XrmoptionNoArg, "0" },
\r
1582 { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
\r
1583 { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
\r
1584 { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
\r
1585 { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
\r
1586 { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
\r
1587 { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
\r
1588 { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
\r
1589 { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
\r
1590 { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
\r
1591 { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
\r
1592 { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
\r
1593 { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
\r
1594 { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
\r
1595 { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
\r
1596 { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
\r
1597 { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
\r
1598 { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
\r
1599 { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
\r
1600 { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
\r
1601 { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
\r
1602 { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
\r
1603 { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
\r
1604 { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
\r
1605 { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
\r
1606 { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
\r
1607 { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
\r
1608 { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
\r
1609 { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
\r
1610 { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
\r
1611 { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
\r
1612 { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
\r
1613 { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
\r
1614 { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
\r
1615 { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
\r
1616 { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
\r
1617 { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
\r
1618 { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
\r
1619 { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
\r
1620 { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
\r
1621 { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
\r
1622 { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
\r
1623 { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
\r
1624 { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
\r
1625 { "-animate", "animateMoving", XrmoptionNoArg, "True" },
\r
1626 { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
\r
1627 { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
\r
1628 { "-drag", "animateDragging", XrmoptionNoArg, "True" },
\r
1629 { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
\r
1630 { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
\r
1631 { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
\r
1632 { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
\r
1633 { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
\r
1634 { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
\r
1635 { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
\r
1636 { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
\r
1637 { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
\r
1638 { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
\r
1639 { "-mode", "initialMode", XrmoptionSepArg, NULL },
\r
1640 { "-variant", "variant", XrmoptionSepArg, NULL },
\r
1641 { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
\r
1642 { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
\r
1643 { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
\r
1644 { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
\r
1645 { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
\r
1646 /* [AS,HR] New features */
\r
1647 { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
\r
1648 { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
\r
1649 { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
\r
1650 { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
\r
1651 { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
\r
1652 { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
\r
1653 { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
\r
1654 { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
\r
1655 { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
\r
1656 { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
\r
1657 { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
\r
1658 { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
\r
1659 { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1660 { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1661 { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
\r
1662 { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
\r
1663 { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
\r
1664 { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
\r
1665 { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
\r
1666 { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
\r
1667 { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
\r
1668 // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
\r
1670 /* [HGM,HR] User-selectable board size */
\r
1671 { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
\r
1672 { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
\r
1673 { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
\r
1675 /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
\r
1676 { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
\r
1677 { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL }, // requires front-end changes to work
\r
1678 { "-allWhite", "allWhite", XrmoptionSepArg, NULL }, // requires front-end changes to work
\r
1679 { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
\r
1680 { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
\r
1681 { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
\r
1682 { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
\r
1683 { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
\r
1684 { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
\r
1685 { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
\r
1686 { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
\r
1687 { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
\r
1688 { "-userName", "userName", XrmoptionSepArg, NULL },
\r
1689 { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
\r
1690 { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
\r
1691 { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
\r
1692 { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
\r
1693 { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
\r
1694 { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
\r
1695 { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
\r
1696 { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
\r
1697 { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
\r
1698 { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
\r
1699 { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
\r
1700 { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
\r
1701 { "-userName", "userName", XrmoptionSepArg, NULL },
\r
1702 { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
\r
1703 { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
\r
1704 { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
\r
1705 { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
\r
1706 { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
\r
1707 { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
\r
1708 { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
\r
1709 { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
\r
1713 XtActionsRec boardActions[] = {
\r
1714 { "DrawPosition", DrawPositionProc },
\r
1715 { "HandleUserMove", HandleUserMove },
\r
1716 { "AnimateUserMove", AnimateUserMove },
\r
1717 { "FileNameAction", FileNameAction },
\r
1718 { "AskQuestionProc", AskQuestionProc },
\r
1719 { "AskQuestionReplyAction", AskQuestionReplyAction },
\r
1720 { "PieceMenuPopup", PieceMenuPopup },
\r
1721 { "WhiteClock", WhiteClock },
\r
1722 { "BlackClock", BlackClock },
\r
1723 { "Iconify", Iconify },
\r
1724 { "ResetProc", ResetProc },
\r
1725 { "LoadGameProc", LoadGameProc },
\r
1726 { "LoadNextGameProc", LoadNextGameProc },
\r
1727 { "LoadPrevGameProc", LoadPrevGameProc },
\r
1728 { "LoadSelectedProc", LoadSelectedProc },
\r
1729 { "ReloadGameProc", ReloadGameProc },
\r
1730 { "LoadPositionProc", LoadPositionProc },
\r
1731 { "LoadNextPositionProc", LoadNextPositionProc },
\r
1732 { "LoadPrevPositionProc", LoadPrevPositionProc },
\r
1733 { "ReloadPositionProc", ReloadPositionProc },
\r
1734 { "CopyPositionProc", CopyPositionProc },
\r
1735 { "PastePositionProc", PastePositionProc },
\r
1736 { "CopyGameProc", CopyGameProc },
\r
1737 { "PasteGameProc", PasteGameProc },
\r
1738 { "SaveGameProc", SaveGameProc },
\r
1739 { "SavePositionProc", SavePositionProc },
\r
1740 { "MailMoveProc", MailMoveProc },
\r
1741 { "ReloadCmailMsgProc", ReloadCmailMsgProc },
\r
1742 { "QuitProc", QuitProc },
\r
1743 { "MachineWhiteProc", MachineWhiteProc },
\r
1744 { "MachineBlackProc", MachineBlackProc },
\r
1745 { "AnalysisModeProc", AnalyzeModeProc },
\r
1746 { "AnalyzeFileProc", AnalyzeFileProc },
\r
1747 { "TwoMachinesProc", TwoMachinesProc },
\r
1748 { "IcsClientProc", IcsClientProc },
\r
1749 { "EditGameProc", EditGameProc },
\r
1750 { "EditPositionProc", EditPositionProc },
\r
1751 { "TrainingProc", EditPositionProc },
\r
1752 { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
\r
1753 { "ShowGameListProc", ShowGameListProc },
\r
1754 { "ShowMoveListProc", HistoryShowProc},
\r
1755 { "EditTagsProc", EditCommentProc },
\r
1756 { "EditCommentProc", EditCommentProc },
\r
1757 { "IcsAlarmProc", IcsAlarmProc },
\r
1758 { "IcsInputBoxProc", IcsInputBoxProc },
\r
1759 { "PauseProc", PauseProc },
\r
1760 { "AcceptProc", AcceptProc },
\r
1761 { "DeclineProc", DeclineProc },
\r
1762 { "RematchProc", RematchProc },
\r
1763 { "CallFlagProc", CallFlagProc },
\r
1764 { "DrawProc", DrawProc },
\r
1765 { "AdjournProc", AdjournProc },
\r
1766 { "AbortProc", AbortProc },
\r
1767 { "ResignProc", ResignProc },
\r
1768 { "EnterKeyProc", EnterKeyProc },
\r
1769 { "StopObservingProc", StopObservingProc },
\r
1770 { "StopExaminingProc", StopExaminingProc },
\r
1771 { "BackwardProc", BackwardProc },
\r
1772 { "ForwardProc", ForwardProc },
\r
1773 { "ToStartProc", ToStartProc },
\r
1774 { "ToEndProc", ToEndProc },
\r
1775 { "RevertProc", RevertProc },
\r
1776 { "TruncateGameProc", TruncateGameProc },
\r
1777 { "MoveNowProc", MoveNowProc },
\r
1778 { "RetractMoveProc", RetractMoveProc },
\r
1779 { "AlwaysQueenProc", AlwaysQueenProc },
\r
1780 { "AnimateDraggingProc", AnimateDraggingProc },
\r
1781 { "AnimateMovingProc", AnimateMovingProc },
\r
1782 { "AutoflagProc", AutoflagProc },
\r
1783 { "AutoflipProc", AutoflipProc },
\r
1784 { "AutobsProc", AutobsProc },
\r
1785 { "AutoraiseProc", AutoraiseProc },
\r
1786 { "AutosaveProc", AutosaveProc },
\r
1787 { "BlindfoldProc", BlindfoldProc },
\r
1788 { "FlashMovesProc", FlashMovesProc },
\r
1789 { "FlipViewProc", FlipViewProc },
\r
1790 { "GetMoveListProc", GetMoveListProc },
\r
1792 { "HighlightDraggingProc", HighlightDraggingProc },
\r
1794 { "HighlightLastMoveProc", HighlightLastMoveProc },
\r
1795 { "IcsAlarmProc", IcsAlarmProc },
\r
1796 { "MoveSoundProc", MoveSoundProc },
\r
1797 { "OldSaveStyleProc", OldSaveStyleProc },
\r
1798 { "PeriodicUpdatesProc", PeriodicUpdatesProc },
\r
1799 { "PonderNextMoveProc", PonderNextMoveProc },
\r
1800 { "PopupExitMessageProc", PopupExitMessageProc },
\r
1801 { "PopupMoveErrorsProc", PopupMoveErrorsProc },
\r
1802 { "PremoveProc", PremoveProc },
\r
1803 { "QuietPlayProc", QuietPlayProc },
\r
1804 { "ShowCoordsProc", ShowCoordsProc },
\r
1805 { "ShowThinkingProc", ShowThinkingProc },
\r
1806 { "HideThinkingProc", HideThinkingProc },
\r
1807 { "TestLegalityProc", TestLegalityProc },
\r
1808 { "InfoProc", InfoProc },
\r
1809 { "ManProc", ManProc },
\r
1810 { "HintProc", HintProc },
\r
1811 { "BookProc", BookProc },
\r
1812 { "AboutGameProc", AboutGameProc },
\r
1813 { "AboutProc", AboutProc },
\r
1814 { "DebugProc", DebugProc },
\r
1815 { "NothingProc", NothingProc },
\r
1816 { "CommentPopDown", (XtActionProc) CommentPopDown },
\r
1817 { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
\r
1818 { "TagsPopDown", (XtActionProc) TagsPopDown },
\r
1819 { "ErrorPopDown", (XtActionProc) ErrorPopDown },
\r
1820 { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
\r
1821 { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
\r
1822 { "FileNamePopDown", (XtActionProc) FileNamePopDown },
\r
1823 { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
\r
1824 { "GameListPopDown", (XtActionProc) GameListPopDown },
\r
1825 { "PromotionPopDown", (XtActionProc) PromotionPopDown },
\r
1826 { "HistoryPopDown", (XtActionProc) HistoryPopDown },
\r
1827 { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
\r
1828 { "ShufflePopDown", (XtActionProc) ShufflePopDown },
\r
1829 { "EnginePopDown", (XtActionProc) EnginePopDown },
\r
1830 { "UciPopDown", (XtActionProc) UciPopDown },
\r
1831 { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
\r
1832 { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
\r
1833 { "SettingsPopDown", (XtActionProc) SettingsPopDown },
\r
1836 char globalTranslations[] =
\r
1837 ":<Key>R: ResignProc() \n \
\r
1838 :<Key>r: ResetProc() \n \
\r
1839 :<Key>g: LoadGameProc() \n \
\r
1840 :<Key>N: LoadNextGameProc() \n \
\r
1841 :<Key>P: LoadPrevGameProc() \n \
\r
1842 :<Key>Q: QuitProc() \n \
\r
1843 :<Key>F: ToEndProc() \n \
\r
1844 :<Key>f: ForwardProc() \n \
\r
1845 :<Key>B: ToStartProc() \n \
\r
1846 :<Key>b: BackwardProc() \n \
\r
1847 :<Key>p: PauseProc() \n \
\r
1848 :<Key>d: DrawProc() \n \
\r
1849 :<Key>t: CallFlagProc() \n \
\r
1850 :<Key>i: Iconify() \n \
\r
1851 :<Key>c: Iconify() \n \
\r
1852 :<Key>v: FlipViewProc() \n \
\r
1853 <KeyDown>Control_L: BackwardProc() \n \
\r
1854 <KeyUp>Control_L: ForwardProc() \n \
\r
1855 <KeyDown>Control_R: BackwardProc() \n \
\r
1856 <KeyUp>Control_R: ForwardProc() \n \
\r
1857 Shift<Key>1: AskQuestionProc(\"Direct command\",\
\r
1858 \"Send to chess program:\",,1) \n \
\r
1859 Shift<Key>2: AskQuestionProc(\"Direct command\",\
\r
1860 \"Send to second chess program:\",,2) \n";
\r
1862 char boardTranslations[] =
\r
1863 "<Btn1Down>: HandleUserMove() \n \
\r
1864 <Btn1Up>: HandleUserMove() \n \
\r
1865 <Btn1Motion>: AnimateUserMove() \n \
\r
1866 Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
\r
1867 PieceMenuPopup(menuB) \n \
\r
1868 Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
\r
1869 PieceMenuPopup(menuW) \n \
\r
1870 Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
\r
1871 PieceMenuPopup(menuW) \n \
\r
1872 Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
\r
1873 PieceMenuPopup(menuB) \n";
\r
1875 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
\r
1876 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
\r
1878 char ICSInputTranslations[] =
\r
1879 "<Key>Return: EnterKeyProc() \n";
\r
1881 String xboardResources[] = {
\r
1882 "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
\r
1883 "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
\r
1884 "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
\r
1889 /* Max possible square size */
\r
1890 #define MAXSQSIZE 256
\r
1892 static int xpm_avail[MAXSQSIZE];
\r
1894 #ifdef HAVE_DIR_STRUCT
\r
1896 /* Extract piece size from filename */
\r
1898 xpm_getsize(name, len, ext)
\r
1909 if ((p=strchr(name, '.')) == NULL ||
\r
1910 StrCaseCmp(p+1, ext) != 0)
\r
1916 while (*p && isdigit(*p))
\r
1923 /* Setup xpm_avail */
\r
1925 xpm_getavail(dirname, ext)
\r
1930 struct dirent *ent;
\r
1933 for (i=0; i<MAXSQSIZE; ++i)
\r
1936 if (appData.debugMode)
\r
1937 fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
\r
1939 dir = opendir(dirname);
\r
1942 fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
\r
1943 programName, dirname);
\r
1947 while ((ent=readdir(dir)) != NULL) {
\r
1948 i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
\r
1949 if (i > 0 && i < MAXSQSIZE)
\r
1959 xpm_print_avail(fp, ext)
\r
1965 fprintf(fp, _("Available `%s' sizes:\n"), ext);
\r
1966 for (i=1; i<MAXSQSIZE; ++i) {
\r
1968 printf("%d\n", i);
\r
1972 /* Return XPM piecesize closest to size */
\r
1974 xpm_closest_to(dirname, size, ext)
\r
1980 int sm_diff = MAXSQSIZE;
\r
1984 xpm_getavail(dirname, ext);
\r
1986 if (appData.debugMode)
\r
1987 xpm_print_avail(stderr, ext);
\r
1989 for (i=1; i<MAXSQSIZE; ++i) {
\r
1990 if (xpm_avail[i]) {
\r
1992 diff = (diff<0) ? -diff : diff;
\r
1993 if (diff < sm_diff) {
\r
2001 fprintf(stderr, _("Error: No `%s' files!\n"), ext);
\r
2007 #else /* !HAVE_DIR_STRUCT */
\r
2008 /* If we are on a system without a DIR struct, we can't
\r
2009 read the directory, so we can't collect a list of
\r
2010 filenames, etc., so we can't do any size-fitting. */
\r
2012 xpm_closest_to(dirname, size, ext)
\r
2017 fprintf(stderr, _("\
\r
2018 Warning: No DIR structure found on this system --\n\
\r
2019 Unable to autosize for XPM/XIM pieces.\n\
\r
2020 Please report this error to frankm@hiwaay.net.\n\
\r
2021 Include system type & operating system in message.\n"));
\r
2024 #endif /* HAVE_DIR_STRUCT */
\r
2026 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
\r
2027 "magenta", "cyan", "white" };
\r
2031 TextColors textColors[(int)NColorClasses];
\r
2033 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
\r
2035 parse_color(str, which)
\r
2039 char *p, buf[100], *d;
\r
2042 if (strlen(str) > 99) /* watch bounds on buf */
\r
2047 for (i=0; i<which; ++i) {
\r
2048 p = strchr(p, ',');
\r
2054 /* Could be looking at something like:
\r
2056 .. in which case we want to stop on a comma also */
\r
2057 while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
\r
2061 return -1; /* Use default for empty field */
\r
2064 if (which == 2 || isdigit(*p))
\r
2067 while (*p && isalpha(*p))
\r
2072 for (i=0; i<8; ++i) {
\r
2073 if (!StrCaseCmp(buf, cnames[i]))
\r
2074 return which? (i+40) : (i+30);
\r
2076 if (!StrCaseCmp(buf, "default")) return -1;
\r
2078 fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
\r
2083 parse_cpair(cc, str)
\r
2087 if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
\r
2088 fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
\r
2089 programName, str);
\r
2093 /* bg and attr are optional */
\r
2094 textColors[(int)cc].bg = parse_color(str, 1);
\r
2095 if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
\r
2096 textColors[(int)cc].attr = 0;
\r
2102 /* Arrange to catch delete-window events */
\r
2103 Atom wm_delete_window;
\r
2105 CatchDeleteWindow(Widget w, String procname)
\r
2107 char buf[MSG_SIZ];
\r
2108 XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
\r
2109 sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
\r
2110 XtAugmentTranslations(w, XtParseTranslationTable(buf));
\r
2117 XtSetArg(args[0], XtNiconic, False);
\r
2118 XtSetValues(shellWidget, args, 1);
\r
2120 XtPopup(shellWidget, XtGrabNone); /* Raise if lowered */
\r
2124 // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
\r
2126 #define BoardSize int
\r
2127 void InitDrawingSizes(BoardSize boardSize, int flags)
\r
2128 { // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
\r
2129 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
\r
2131 XtGeometryResult gres;
\r
2134 if(!formWidget) return;
\r
2137 * Enable shell resizing.
\r
2139 shellArgs[0].value = (XtArgVal) &w;
\r
2140 shellArgs[1].value = (XtArgVal) &h;
\r
2141 XtGetValues(shellWidget, shellArgs, 2);
\r
2143 shellArgs[4].value = 2*w; shellArgs[2].value = 10;
\r
2144 shellArgs[5].value = 2*h; shellArgs[3].value = 10;
\r
2145 XtSetValues(shellWidget, &shellArgs[2], 4);
\r
2147 XtSetArg(args[0], XtNdefaultDistance, &sep);
\r
2148 XtGetValues(formWidget, args, 1);
\r
2150 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
2151 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
2154 XtSetArg(args[0], XtNwidth, boardWidth);
\r
2155 XtSetArg(args[1], XtNheight, boardHeight);
\r
2156 XtSetValues(boardWidget, args, 2);
\r
2158 timerWidth = (boardWidth - sep) / 2;
\r
2159 XtSetArg(args[0], XtNwidth, timerWidth);
\r
2160 XtSetValues(whiteTimerWidget, args, 1);
\r
2161 XtSetValues(blackTimerWidget, args, 1);
\r
2163 XawFormDoLayout(formWidget, False);
\r
2165 if (appData.titleInWindow) {
\r
2167 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2168 XtSetArg(args[i], XtNheight, &h); i++;
\r
2169 XtGetValues(titleWidget, args, i);
\r
2170 if (smallLayout) {
\r
2171 w = boardWidth - 2*bor;
\r
2173 XtSetArg(args[0], XtNwidth, &w);
\r
2174 XtGetValues(menuBarWidget, args, 1);
\r
2175 w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
\r
2178 gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
\r
2179 if (gres != XtGeometryYes && appData.debugMode) {
\r
2181 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
\r
2182 programName, gres, w, h, wr, hr);
\r
2186 XawFormDoLayout(formWidget, True);
\r
2189 * Inhibit shell resizing.
\r
2191 shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
\r
2192 shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
\r
2193 shellArgs[4].value = shellArgs[2].value = w;
\r
2194 shellArgs[5].value = shellArgs[3].value = h;
\r
2195 XtSetValues(shellWidget, &shellArgs[0], 6);
\r
2204 int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
\r
2205 XSetWindowAttributes window_attributes;
\r
2207 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
\r
2208 XrmValue vFrom, vTo;
\r
2209 XtGeometryResult gres;
\r
2212 int forceMono = False;
\r
2213 #define INDIRECTION
\r
2214 #ifdef INDIRECTION
\r
2215 // [HGM] before anything else, expand any indirection files amongst options
\r
2216 char *argvCopy[1000]; // 1000 seems enough
\r
2217 char newArgs[10000]; // holds actual characters
\r
2220 srandom(time(0)); // [HGM] book: make random truly random
\r
2223 for(i=0; i<argc; i++) {
\r
2224 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
\r
2225 //fprintf(stderr, "arg %s\n", argv[i]);
\r
2226 if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
\r
2228 FILE *f = fopen(argv[i]+1, "rb");
\r
2229 if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
\r
2230 argvCopy[j++] = newArgs + k; // get ready for first argument from file
\r
2231 while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
\r
2233 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
\r
2234 newArgs[k++] = 0; // terminate current arg
\r
2235 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
\r
2236 argvCopy[j++] = newArgs + k; // get ready for next
\r
2238 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
\r
2247 argvCopy[j] = NULL;
\r
2251 if(appData.debugMode,1) { // OK, appData is not initialized here yet...
\r
2252 for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
\r
2258 setbuf(stdout, NULL);
\r
2259 setbuf(stderr, NULL);
\r
2262 programName = strrchr(argv[0], '/');
\r
2263 if (programName == NULL)
\r
2264 programName = argv[0];
\r
2269 XtSetLanguageProc(NULL, NULL, NULL);
\r
2270 bindtextdomain(PRODUCT, LOCALEDIR);
\r
2271 bind_textdomain_codeset(PRODUCT, "UTF-8");
\r
2272 textdomain(PRODUCT);
\r
2276 XtAppInitialize(&appContext, "XBoard", shellOptions,
\r
2277 XtNumber(shellOptions),
\r
2278 &argc, argv, xboardResources, NULL, 0);
\r
2280 fprintf(stderr, _("%s: unrecognized argument %s\n"),
\r
2281 programName, argv[1]);
\r
2285 if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
\r
2288 if (chdir(chessDir) != 0) {
\r
2289 fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
\r
2295 p = getenv("HOME");
\r
2296 if (p == NULL) p = "/tmp";
\r
2297 i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
\r
2298 gameCopyFilename = (char*) malloc(i);
\r
2299 gamePasteFilename = (char*) malloc(i);
\r
2300 sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
\r
2301 sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
\r
2303 XtGetApplicationResources(shellWidget, (XtPointer) &appData,
\r
2304 clientResources, XtNumber(clientResources),
\r
2307 if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
\r
2308 /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
\r
2309 if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL) {
\r
2310 printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
\r
2313 setbuf(debugFP, NULL);
\r
2316 /* [HGM,HR] make sure board size is acceptable */
\r
2317 if(appData.NrFiles > BOARD_SIZE ||
\r
2318 appData.NrRanks > BOARD_SIZE )
\r
2319 DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
\r
2322 /* This feature does not work; animation needs a rewrite */
\r
2323 appData.highlightDragging = FALSE;
\r
2327 xDisplay = XtDisplay(shellWidget);
\r
2328 xScreen = DefaultScreen(xDisplay);
\r
2329 wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
\r
2331 gameInfo.variant = StringToVariant(appData.variant);
\r
2332 InitPosition(FALSE);
\r
2335 * Determine boardSize
\r
2337 gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
\r
2340 // [HGM] as long as we have not created the possibility to change size while running, start with requested size
\r
2341 gameInfo.boardWidth = appData.NrFiles > 0 ? appData.NrFiles : 8;
\r
2342 gameInfo.boardHeight = appData.NrRanks > 0 ? appData.NrRanks : 8;
\r
2343 gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
\r
2348 InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
\r
2350 if (isdigit(appData.boardSize[0])) {
\r
2351 i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
\r
2352 &lineGap, &clockFontPxlSize, &coordFontPxlSize,
\r
2353 &fontPxlSize, &smallLayout, &tinyLayout);
\r
2355 fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
\r
2356 programName, appData.boardSize);
\r
2360 /* Find some defaults; use the nearest known size */
\r
2361 SizeDefaults *szd, *nearest;
\r
2362 int distance = 99999;
\r
2363 nearest = szd = sizeDefaults;
\r
2364 while (szd->name != NULL) {
\r
2365 if (abs(szd->squareSize - squareSize) < distance) {
\r
2367 distance = abs(szd->squareSize - squareSize);
\r
2368 if (distance == 0) break;
\r
2372 if (i < 2) lineGap = nearest->lineGap;
\r
2373 if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
\r
2374 if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
\r
2375 if (i < 5) fontPxlSize = nearest->fontPxlSize;
\r
2376 if (i < 6) smallLayout = nearest->smallLayout;
\r
2377 if (i < 7) tinyLayout = nearest->tinyLayout;
\r
2380 SizeDefaults *szd = sizeDefaults;
\r
2381 if (*appData.boardSize == NULLCHAR) {
\r
2382 while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
\r
2383 DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
\r
2386 if (szd->name == NULL) szd--;
\r
2388 while (szd->name != NULL &&
\r
2389 StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
\r
2390 if (szd->name == NULL) {
\r
2391 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
\r
2392 programName, appData.boardSize);
\r
2396 squareSize = szd->squareSize;
\r
2397 lineGap = szd->lineGap;
\r
2398 clockFontPxlSize = szd->clockFontPxlSize;
\r
2399 coordFontPxlSize = szd->coordFontPxlSize;
\r
2400 fontPxlSize = szd->fontPxlSize;
\r
2401 smallLayout = szd->smallLayout;
\r
2402 tinyLayout = szd->tinyLayout;
\r
2405 /* Now, using squareSize as a hint, find a good XPM/XIM set size */
\r
2406 if (strlen(appData.pixmapDirectory) > 0) {
\r
2407 p = ExpandPathName(appData.pixmapDirectory);
\r
2409 fprintf(stderr, _("Error expanding path name \"%s\"\n"),
\r
2410 appData.pixmapDirectory);
\r
2413 if (appData.debugMode) {
\r
2414 fprintf(stderr, _("\
\r
2415 XBoard square size (hint): %d\n\
\r
2416 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
\r
2418 squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
\r
2419 if (appData.debugMode) {
\r
2420 fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
\r
2424 /* [HR] height treated separately (hacked) */
\r
2425 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
2426 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
2427 if (appData.showJail == 1) {
\r
2428 /* Jail on top and bottom */
\r
2429 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
\r
2430 XtSetArg(boardArgs[2], XtNheight,
\r
2431 boardHeight + 2*(lineGap + squareSize));
\r
2432 } else if (appData.showJail == 2) {
\r
2433 /* Jail on sides */
\r
2434 XtSetArg(boardArgs[1], XtNwidth,
\r
2435 boardWidth + 2*(lineGap + squareSize));
\r
2436 XtSetArg(boardArgs[2], XtNheight, boardHeight);
\r
2439 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
\r
2440 XtSetArg(boardArgs[2], XtNheight, boardHeight);
\r
2444 * Determine what fonts to use.
\r
2446 appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
\r
2447 clockFontID = XLoadFont(xDisplay, appData.clockFont);
\r
2448 clockFontStruct = XQueryFont(xDisplay, clockFontID);
\r
2449 appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
\r
2450 coordFontID = XLoadFont(xDisplay, appData.coordFont);
\r
2451 coordFontStruct = XQueryFont(xDisplay, coordFontID);
\r
2452 appData.font = FindFont(appData.font, fontPxlSize);
\r
2453 countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
\r
2454 countFontStruct = XQueryFont(xDisplay, countFontID);
\r
2455 // appData.font = FindFont(appData.font, fontPxlSize);
\r
2457 xdb = XtDatabase(xDisplay);
\r
2458 XrmPutStringResource(&xdb, "*font", appData.font);
\r
2461 * Detect if there are not enough colors available and adapt.
\r
2463 if (DefaultDepth(xDisplay, xScreen) <= 2) {
\r
2464 appData.monoMode = True;
\r
2467 if (!appData.monoMode) {
\r
2468 vFrom.addr = (caddr_t) appData.lightSquareColor;
\r
2469 vFrom.size = strlen(appData.lightSquareColor);
\r
2470 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2471 if (vTo.addr == NULL) {
\r
2472 appData.monoMode = True;
\r
2475 lightSquareColor = *(Pixel *) vTo.addr;
\r
2478 if (!appData.monoMode) {
\r
2479 vFrom.addr = (caddr_t) appData.darkSquareColor;
\r
2480 vFrom.size = strlen(appData.darkSquareColor);
\r
2481 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2482 if (vTo.addr == NULL) {
\r
2483 appData.monoMode = True;
\r
2486 darkSquareColor = *(Pixel *) vTo.addr;
\r
2489 if (!appData.monoMode) {
\r
2490 vFrom.addr = (caddr_t) appData.whitePieceColor;
\r
2491 vFrom.size = strlen(appData.whitePieceColor);
\r
2492 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2493 if (vTo.addr == NULL) {
\r
2494 appData.monoMode = True;
\r
2497 whitePieceColor = *(Pixel *) vTo.addr;
\r
2500 if (!appData.monoMode) {
\r
2501 vFrom.addr = (caddr_t) appData.blackPieceColor;
\r
2502 vFrom.size = strlen(appData.blackPieceColor);
\r
2503 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2504 if (vTo.addr == NULL) {
\r
2505 appData.monoMode = True;
\r
2508 blackPieceColor = *(Pixel *) vTo.addr;
\r
2512 if (!appData.monoMode) {
\r
2513 vFrom.addr = (caddr_t) appData.highlightSquareColor;
\r
2514 vFrom.size = strlen(appData.highlightSquareColor);
\r
2515 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2516 if (vTo.addr == NULL) {
\r
2517 appData.monoMode = True;
\r
2520 highlightSquareColor = *(Pixel *) vTo.addr;
\r
2524 if (!appData.monoMode) {
\r
2525 vFrom.addr = (caddr_t) appData.premoveHighlightColor;
\r
2526 vFrom.size = strlen(appData.premoveHighlightColor);
\r
2527 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2528 if (vTo.addr == NULL) {
\r
2529 appData.monoMode = True;
\r
2532 premoveHighlightColor = *(Pixel *) vTo.addr;
\r
2537 fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
\r
2541 if (appData.monoMode && appData.debugMode) {
\r
2542 fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
\r
2543 (unsigned long) XWhitePixel(xDisplay, xScreen),
\r
2544 (unsigned long) XBlackPixel(xDisplay, xScreen));
\r
2547 if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
\r
2548 parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
\r
2549 parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||
\r
2550 parse_cpair(ColorChannel, appData.colorChannel) < 0 ||
\r
2551 parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
\r
2552 parse_cpair(ColorTell, appData.colorTell) < 0 ||
\r
2553 parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||
\r
2554 parse_cpair(ColorRequest, appData.colorRequest) < 0 ||
\r
2555 parse_cpair(ColorSeek, appData.colorSeek) < 0 ||
\r
2556 parse_cpair(ColorNormal, appData.colorNormal) < 0)
\r
2558 if (appData.colorize) {
\r
2560 _("%s: can't parse color names; disabling colorization\n"),
\r
2563 appData.colorize = FALSE;
\r
2565 textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
\r
2566 textColors[ColorNone].attr = 0;
\r
2568 XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
\r
2571 * widget hierarchy
\r
2574 layoutName = "tinyLayout";
\r
2575 } else if (smallLayout) {
\r
2576 layoutName = "smallLayout";
\r
2578 layoutName = "normalLayout";
\r
2580 /* Outer layoutWidget is there only to provide a name for use in
\r
2581 resources that depend on the layout style */
\r
2583 XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
\r
2584 layoutArgs, XtNumber(layoutArgs));
\r
2586 XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
\r
2587 formArgs, XtNumber(formArgs));
\r
2588 XtSetArg(args[0], XtNdefaultDistance, &sep);
\r
2589 XtGetValues(formWidget, args, 1);
\r
2592 widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
\r
2593 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2594 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2595 XtSetValues(menuBarWidget, args, 2);
\r
2597 widgetList[j++] = whiteTimerWidget =
\r
2598 XtCreateWidget("whiteTime", labelWidgetClass,
\r
2599 formWidget, timerArgs, XtNumber(timerArgs));
\r
2600 XtSetArg(args[0], XtNfont, clockFontStruct);
\r
2601 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2602 XtSetArg(args[2], XtNbottom, XtChainTop);
\r
2603 XtSetValues(whiteTimerWidget, args, 3);
\r
2605 widgetList[j++] = blackTimerWidget =
\r
2606 XtCreateWidget("blackTime", labelWidgetClass,
\r
2607 formWidget, timerArgs, XtNumber(timerArgs));
\r
2608 XtSetArg(args[0], XtNfont, clockFontStruct);
\r
2609 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2610 XtSetArg(args[2], XtNbottom, XtChainTop);
\r
2611 XtSetValues(blackTimerWidget, args, 3);
\r
2613 if (appData.titleInWindow) {
\r
2614 widgetList[j++] = titleWidget =
\r
2615 XtCreateWidget("title", labelWidgetClass, formWidget,
\r
2616 titleArgs, XtNumber(titleArgs));
\r
2617 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2618 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2619 XtSetValues(titleWidget, args, 2);
\r
2622 if (appData.showButtonBar) {
\r
2623 widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
\r
2624 XtSetArg(args[0], XtNleft, XtChainRight); // [HGM] glue to right window edge
\r
2625 XtSetArg(args[1], XtNright, XtChainRight); // for good run-time sizing
\r
2626 XtSetArg(args[2], XtNtop, XtChainTop);
\r
2627 XtSetArg(args[3], XtNbottom, XtChainTop);
\r
2628 XtSetValues(buttonBarWidget, args, 4);
\r
2631 widgetList[j++] = messageWidget =
\r
2632 XtCreateWidget("message", labelWidgetClass, formWidget,
\r
2633 messageArgs, XtNumber(messageArgs));
\r
2634 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2635 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2636 XtSetValues(messageWidget, args, 2);
\r
2638 widgetList[j++] = boardWidget =
\r
2639 XtCreateWidget("board", widgetClass, formWidget, boardArgs,
\r
2640 XtNumber(boardArgs));
\r
2642 XtManageChildren(widgetList, j);
\r
2644 timerWidth = (boardWidth - sep) / 2;
\r
2645 XtSetArg(args[0], XtNwidth, timerWidth);
\r
2646 XtSetValues(whiteTimerWidget, args, 1);
\r
2647 XtSetValues(blackTimerWidget, args, 1);
\r
2649 XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
\r
2650 XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
\r
2651 XtGetValues(whiteTimerWidget, args, 2);
\r
2653 if (appData.showButtonBar) {
\r
2654 XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
\r
2655 XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
\r
2656 XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
\r
2660 * formWidget uses these constraints but they are stored
\r
2661 * in the children.
\r
2664 XtSetArg(args[i], XtNfromHoriz, 0); i++;
\r
2665 XtSetValues(menuBarWidget, args, i);
\r
2666 if (appData.titleInWindow) {
\r
2667 if (smallLayout) {
\r
2669 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2670 XtSetValues(whiteTimerWidget, args, i);
\r
2672 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2673 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2674 XtSetValues(blackTimerWidget, args, i);
\r
2676 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2677 XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
\r
2678 XtSetValues(titleWidget, args, i);
\r
2680 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2681 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2682 XtSetValues(messageWidget, args, i);
\r
2683 if (appData.showButtonBar) {
\r
2685 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2686 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2687 XtSetValues(buttonBarWidget, args, i);
\r
2691 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2692 XtSetValues(whiteTimerWidget, args, i);
\r
2694 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2695 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2696 XtSetValues(blackTimerWidget, args, i);
\r
2698 XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
\r
2699 XtSetValues(titleWidget, args, i);
\r
2701 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2702 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2703 XtSetValues(messageWidget, args, i);
\r
2704 if (appData.showButtonBar) {
\r
2706 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2707 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2708 XtSetValues(buttonBarWidget, args, i);
\r
2713 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2714 XtSetValues(whiteTimerWidget, args, i);
\r
2716 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2717 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2718 XtSetValues(blackTimerWidget, args, i);
\r
2720 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2721 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2722 XtSetValues(messageWidget, args, i);
\r
2723 if (appData.showButtonBar) {
\r
2725 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2726 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2727 XtSetValues(buttonBarWidget, args, i);
\r
2731 XtSetArg(args[0], XtNfromVert, messageWidget);
\r
2732 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2733 XtSetArg(args[2], XtNbottom, XtChainBottom);
\r
2734 XtSetArg(args[3], XtNleft, XtChainLeft);
\r
2735 XtSetArg(args[4], XtNright, XtChainRight);
\r
2736 XtSetValues(boardWidget, args, 5);
\r
2738 XtRealizeWidget(shellWidget);
\r
2741 * Correct the width of the message and title widgets.
\r
2742 * It is not known why some systems need the extra fudge term.
\r
2743 * The value "2" is probably larger than needed.
\r
2745 XawFormDoLayout(formWidget, False);
\r
2747 #define WIDTH_FUDGE 2
\r
2749 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2750 XtSetArg(args[i], XtNheight, &h); i++;
\r
2751 XtGetValues(messageWidget, args, i);
\r
2752 if (appData.showButtonBar) {
\r
2754 XtSetArg(args[i], XtNwidth, &w); i++;
\r
2755 XtGetValues(buttonBarWidget, args, i);
\r
2756 w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
\r
2758 w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
\r
2761 gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
\r
2762 if (gres != XtGeometryYes && appData.debugMode) {
\r
2763 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
\r
2764 programName, gres, w, h, wr, hr);
\r
2767 /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
\r
2768 /* The size used for the child widget in layout lags one resize behind
\r
2769 its true size, so we resize a second time, 1 pixel smaller. Yeech! */
\r
2771 gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
\r
2772 if (gres != XtGeometryYes && appData.debugMode) {
\r
2773 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
\r
2774 programName, gres, w, h, wr, hr);
\r
2777 XtSetArg(args[0], XtNleft, XtChainLeft); // [HGM] glue ends for good run-time sizing
\r
2778 XtSetArg(args[1], XtNright, XtChainRight);
\r
2779 XtSetValues(messageWidget, args, 2);
\r
2781 if (appData.titleInWindow) {
\r
2783 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2784 XtSetArg(args[i], XtNheight, &h); i++;
\r
2785 XtGetValues(titleWidget, args, i);
\r
2786 if (smallLayout) {
\r
2787 w = boardWidth - 2*bor;
\r
2789 XtSetArg(args[0], XtNwidth, &w);
\r
2790 XtGetValues(menuBarWidget, args, 1);
\r
2791 w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
\r
2794 gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
\r
2795 if (gres != XtGeometryYes && appData.debugMode) {
\r
2797 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
\r
2798 programName, gres, w, h, wr, hr);
\r
2801 XawFormDoLayout(formWidget, True);
\r
2803 xBoardWindow = XtWindow(boardWidget);
\r
2805 // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
\r
2806 // not need to go into InitDrawingSizes().
\r
2810 * Create X checkmark bitmap and initialize option menu checks.
\r
2812 ReadBitmap(&xMarkPixmap, "checkmark.bm",
\r
2813 checkmark_bits, checkmark_width, checkmark_height);
\r
2814 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
2815 if (appData.alwaysPromoteToQueen) {
\r
2816 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
\r
2819 if (appData.animateDragging) {
\r
2820 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2821 "menuOptions.Animate Dragging"),
\r
2824 if (appData.animate) {
\r
2825 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
\r
2828 if (appData.autoComment) {
\r
2829 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
\r
2832 if (appData.autoCallFlag) {
\r
2833 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
\r
2836 if (appData.autoFlipView) {
\r
2837 XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
\r
2840 if (appData.autoObserve) {
\r
2841 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
\r
2844 if (appData.autoRaiseBoard) {
\r
2845 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2846 "menuOptions.Auto Raise Board"), args, 1);
\r
2848 if (appData.autoSaveGames) {
\r
2849 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2852 if (appData.saveGameFile[0] != NULLCHAR) {
\r
2853 /* Can't turn this off from menu */
\r
2854 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2856 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2860 if (appData.blindfold) {
\r
2861 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2862 "menuOptions.Blindfold"), args, 1);
\r
2864 if (appData.flashCount > 0) {
\r
2865 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2866 "menuOptions.Flash Moves"),
\r
2869 if (appData.getMoveList) {
\r
2870 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
\r
2874 if (appData.highlightDragging) {
\r
2875 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2876 "menuOptions.Highlight Dragging"),
\r
2880 if (appData.highlightLastMove) {
\r
2881 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2882 "menuOptions.Highlight Last Move"),
\r
2885 if (appData.icsAlarm) {
\r
2886 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
\r
2889 if (appData.ringBellAfterMoves) {
\r
2890 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
\r
2893 if (appData.oldSaveStyle) {
\r
2894 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2895 "menuOptions.Old Save Style"), args, 1);
\r
2897 if (appData.periodicUpdates) {
\r
2898 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2899 "menuOptions.Periodic Updates"), args, 1);
\r
2901 if (appData.ponderNextMove) {
\r
2902 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2903 "menuOptions.Ponder Next Move"), args, 1);
\r
2905 if (appData.popupExitMessage) {
\r
2906 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2907 "menuOptions.Popup Exit Message"), args, 1);
\r
2909 if (appData.popupMoveErrors) {
\r
2910 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2911 "menuOptions.Popup Move Errors"), args, 1);
\r
2913 if (appData.premove) {
\r
2914 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2915 "menuOptions.Premove"), args, 1);
\r
2917 if (appData.quietPlay) {
\r
2918 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2919 "menuOptions.Quiet Play"), args, 1);
\r
2921 if (appData.showCoords) {
\r
2922 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
\r
2925 if (appData.hideThinkingFromHuman) {
\r
2926 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
\r
2929 if (appData.testLegality) {
\r
2930 XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
\r
2937 ReadBitmap(&wIconPixmap, "icon_white.bm",
\r
2938 icon_white_bits, icon_white_width, icon_white_height);
\r
2939 ReadBitmap(&bIconPixmap, "icon_black.bm",
\r
2940 icon_black_bits, icon_black_width, icon_black_height);
\r
2941 iconPixmap = wIconPixmap;
\r
2943 XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;
\r
2944 XtSetValues(shellWidget, args, i);
\r
2947 * Create a cursor for the board widget.
\r
2949 window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
\r
2950 XChangeWindowAttributes(xDisplay, xBoardWindow,
\r
2951 CWCursor, &window_attributes);
\r
2954 * Inhibit shell resizing.
\r
2956 shellArgs[0].value = (XtArgVal) &w;
\r
2957 shellArgs[1].value = (XtArgVal) &h;
\r
2958 XtGetValues(shellWidget, shellArgs, 2);
\r
2959 shellArgs[4].value = shellArgs[2].value = w;
\r
2960 shellArgs[5].value = shellArgs[3].value = h;
\r
2961 XtSetValues(shellWidget, &shellArgs[2], 4);
\r
2962 marginW = w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
\r
2963 marginH = h - boardHeight;
\r
2965 CatchDeleteWindow(shellWidget, "QuitProc");
\r
2970 if (appData.bitmapDirectory[0] != NULLCHAR) {
\r
2973 CreateXPMPieces();
\r
2976 CreateXIMPieces();
\r
2977 /* Create regular pieces */
\r
2978 if (!useImages) CreatePieces();
\r
2981 CreatePieceMenus();
\r
2983 if (appData.animate || appData.animateDragging)
\r
2986 XtAugmentTranslations(formWidget,
\r
2987 XtParseTranslationTable(globalTranslations));
\r
2988 XtAugmentTranslations(boardWidget,
\r
2989 XtParseTranslationTable(boardTranslations));
\r
2990 XtAugmentTranslations(whiteTimerWidget,
\r
2991 XtParseTranslationTable(whiteTranslations));
\r
2992 XtAugmentTranslations(blackTimerWidget,
\r
2993 XtParseTranslationTable(blackTranslations));
\r
2995 /* Why is the following needed on some versions of X instead
\r
2996 * of a translation? */
\r
2997 XtAddEventHandler(boardWidget, ExposureMask, False,
\r
2998 (XtEventHandler) EventProc, NULL);
\r
3003 if (errorExitStatus == -1) {
\r
3004 if (appData.icsActive) {
\r
3005 /* We now wait until we see "login:" from the ICS before
\r
3006 sending the logon script (problems with timestamp otherwise) */
\r
3007 /*ICSInitScript();*/
\r
3008 if (appData.icsInputBox) ICSInputBoxPopUp();
\r
3011 signal(SIGINT, IntSigHandler);
\r
3012 signal(SIGTERM, IntSigHandler);
\r
3013 if (*appData.cmailGameName != NULLCHAR) {
\r
3014 signal(SIGUSR1, CmailSigHandler);
\r
3017 InitPosition(TRUE);
\r
3019 XtAppMainLoop(appContext);
\r
3020 if (appData.debugMode) fclose(debugFP); // [DM] debug
\r
3025 ShutDownFrontEnd()
\r
3027 if (appData.icsActive && oldICSInteractionTitle != NULL) {
\r
3028 DisplayIcsInteractionTitle(oldICSInteractionTitle);
\r
3030 unlink(gameCopyFilename);
\r
3031 unlink(gamePasteFilename);
\r
3035 IntSigHandler(sig)
\r
3042 CmailSigHandler(sig)
\r
3048 signal(SIGUSR1, SIG_IGN); /* suspend handler */
\r
3050 /* Activate call-back function CmailSigHandlerCallBack() */
\r
3051 OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
\r
3053 signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
\r
3057 CmailSigHandlerCallBack(isr, closure, message, count, error)
\r
3058 InputSourceRef isr;
\r
3065 ReloadCmailMsgEvent(TRUE); /* Reload cmail msg */
\r
3067 /**** end signal code ****/
\r
3074 char buf[MSG_SIZ];
\r
3077 f = fopen(appData.icsLogon, "r");
\r
3079 p = getenv("HOME");
\r
3083 strcat(buf, appData.icsLogon);
\r
3084 f = fopen(buf, "r");
\r
3088 ProcessICSInitScript(f);
\r
3095 EditCommentPopDown();
\r
3106 SetMenuEnables(enab)
\r
3110 if (!menuBarWidget) return;
\r
3111 while (enab->name != NULL) {
\r
3112 w = XtNameToWidget(menuBarWidget, enab->name);
\r
3114 DisplayError(enab->name, 0);
\r
3116 XtSetSensitive(w, enab->value);
\r
3122 Enables icsEnables[] = {
\r
3123 { "menuFile.Mail Move", False },
\r
3124 { "menuFile.Reload CMail Message", False },
\r
3125 { "menuMode.Machine Black", False },
\r
3126 { "menuMode.Machine White", False },
\r
3127 { "menuMode.Analysis Mode", False },
\r
3128 { "menuMode.Analyze File", False },
\r
3129 { "menuMode.Two Machines", False },
\r
3131 { "menuHelp.Hint", False },
\r
3132 { "menuHelp.Book", False },
\r
3133 { "menuStep.Move Now", False },
\r
3134 { "menuOptions.Periodic Updates", False },
\r
3135 { "menuOptions.Hide Thinking", False },
\r
3136 { "menuOptions.Ponder Next Move", False },
\r
3141 Enables ncpEnables[] = {
\r
3142 { "menuFile.Mail Move", False },
\r
3143 { "menuFile.Reload CMail Message", False },
\r
3144 { "menuMode.Machine White", False },
\r
3145 { "menuMode.Machine Black", False },
\r
3146 { "menuMode.Analysis Mode", False },
\r
3147 { "menuMode.Analyze File", False },
\r
3148 { "menuMode.Two Machines", False },
\r
3149 { "menuMode.ICS Client", False },
\r
3150 { "menuMode.ICS Input Box", False },
\r
3151 { "Action", False },
\r
3152 { "menuStep.Revert", False },
\r
3153 { "menuStep.Move Now", False },
\r
3154 { "menuStep.Retract Move", False },
\r
3155 { "menuOptions.Auto Comment", False },
\r
3156 { "menuOptions.Auto Flag", False },
\r
3157 { "menuOptions.Auto Flip View", False },
\r
3158 { "menuOptions.Auto Observe", False },
\r
3159 { "menuOptions.Auto Raise Board", False },
\r
3160 { "menuOptions.Get Move List", False },
\r
3161 { "menuOptions.ICS Alarm", False },
\r
3162 { "menuOptions.Move Sound", False },
\r
3163 { "menuOptions.Quiet Play", False },
\r
3164 { "menuOptions.Hide Thinking", False },
\r
3165 { "menuOptions.Periodic Updates", False },
\r
3166 { "menuOptions.Ponder Next Move", False },
\r
3167 { "menuHelp.Hint", False },
\r
3168 { "menuHelp.Book", False },
\r
3172 Enables gnuEnables[] = {
\r
3173 { "menuMode.ICS Client", False },
\r
3174 { "menuMode.ICS Input Box", False },
\r
3175 { "menuAction.Accept", False },
\r
3176 { "menuAction.Decline", False },
\r
3177 { "menuAction.Rematch", False },
\r
3178 { "menuAction.Adjourn", False },
\r
3179 { "menuAction.Stop Examining", False },
\r
3180 { "menuAction.Stop Observing", False },
\r
3181 { "menuStep.Revert", False },
\r
3182 { "menuOptions.Auto Comment", False },
\r
3183 { "menuOptions.Auto Observe", False },
\r
3184 { "menuOptions.Auto Raise Board", False },
\r
3185 { "menuOptions.Get Move List", False },
\r
3186 { "menuOptions.Premove", False },
\r
3187 { "menuOptions.Quiet Play", False },
\r
3189 /* The next two options rely on SetCmailMode being called *after* */
\r
3190 /* SetGNUMode so that when GNU is being used to give hints these */
\r
3191 /* menu options are still available */
\r
3193 { "menuFile.Mail Move", False },
\r
3194 { "menuFile.Reload CMail Message", False },
\r
3198 Enables cmailEnables[] = {
\r
3199 { "Action", True },
\r
3200 { "menuAction.Call Flag", False },
\r
3201 { "menuAction.Draw", True },
\r
3202 { "menuAction.Adjourn", False },
\r
3203 { "menuAction.Abort", False },
\r
3204 { "menuAction.Stop Observing", False },
\r
3205 { "menuAction.Stop Examining", False },
\r
3206 { "menuFile.Mail Move", True },
\r
3207 { "menuFile.Reload CMail Message", True },
\r
3211 Enables trainingOnEnables[] = {
\r
3212 { "menuMode.Edit Comment", False },
\r
3213 { "menuMode.Pause", False },
\r
3214 { "menuStep.Forward", False },
\r
3215 { "menuStep.Backward", False },
\r
3216 { "menuStep.Forward to End", False },
\r
3217 { "menuStep.Back to Start", False },
\r
3218 { "menuStep.Move Now", False },
\r
3219 { "menuStep.Truncate Game", False },
\r
3223 Enables trainingOffEnables[] = {
\r
3224 { "menuMode.Edit Comment", True },
\r
3225 { "menuMode.Pause", True },
\r
3226 { "menuStep.Forward", True },
\r
3227 { "menuStep.Backward", True },
\r
3228 { "menuStep.Forward to End", True },
\r
3229 { "menuStep.Back to Start", True },
\r
3230 { "menuStep.Move Now", True },
\r
3231 { "menuStep.Truncate Game", True },
\r
3235 Enables machineThinkingEnables[] = {
\r
3236 { "menuFile.Load Game", False },
\r
3237 { "menuFile.Load Next Game", False },
\r
3238 { "menuFile.Load Previous Game", False },
\r
3239 { "menuFile.Reload Same Game", False },
\r
3240 { "menuFile.Paste Game", False },
\r
3241 { "menuFile.Load Position", False },
\r
3242 { "menuFile.Load Next Position", False },
\r
3243 { "menuFile.Load Previous Position", False },
\r
3244 { "menuFile.Reload Same Position", False },
\r
3245 { "menuFile.Paste Position", False },
\r
3246 { "menuMode.Machine White", False },
\r
3247 { "menuMode.Machine Black", False },
\r
3248 { "menuMode.Two Machines", False },
\r
3249 { "menuStep.Retract Move", False },
\r
3253 Enables userThinkingEnables[] = {
\r
3254 { "menuFile.Load Game", True },
\r
3255 { "menuFile.Load Next Game", True },
\r
3256 { "menuFile.Load Previous Game", True },
\r
3257 { "menuFile.Reload Same Game", True },
\r
3258 { "menuFile.Paste Game", True },
\r
3259 { "menuFile.Load Position", True },
\r
3260 { "menuFile.Load Next Position", True },
\r
3261 { "menuFile.Load Previous Position", True },
\r
3262 { "menuFile.Reload Same Position", True },
\r
3263 { "menuFile.Paste Position", True },
\r
3264 { "menuMode.Machine White", True },
\r
3265 { "menuMode.Machine Black", True },
\r
3266 { "menuMode.Two Machines", True },
\r
3267 { "menuStep.Retract Move", True },
\r
3273 SetMenuEnables(icsEnables);
\r
3276 if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */
\r
3277 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
\r
3284 SetMenuEnables(ncpEnables);
\r
3290 SetMenuEnables(gnuEnables);
\r
3296 SetMenuEnables(cmailEnables);
\r
3300 SetTrainingModeOn()
\r
3302 SetMenuEnables(trainingOnEnables);
\r
3303 if (appData.showButtonBar) {
\r
3304 XtSetSensitive(buttonBarWidget, False);
\r
3310 SetTrainingModeOff()
\r
3312 SetMenuEnables(trainingOffEnables);
\r
3313 if (appData.showButtonBar) {
\r
3314 XtSetSensitive(buttonBarWidget, True);
\r
3319 SetUserThinkingEnables()
\r
3321 if (appData.noChessProgram) return;
\r
3322 SetMenuEnables(userThinkingEnables);
\r
3326 SetMachineThinkingEnables()
\r
3328 if (appData.noChessProgram) return;
\r
3329 SetMenuEnables(machineThinkingEnables);
\r
3330 switch (gameMode) {
\r
3331 case MachinePlaysBlack:
\r
3332 case MachinePlaysWhite:
\r
3333 case TwoMachinesPlay:
\r
3334 XtSetSensitive(XtNameToWidget(menuBarWidget,
\r
3335 ModeToWidgetName(gameMode)), True);
\r
3342 #define Abs(n) ((n)<0 ? -(n) : (n))
\r
3345 * Find a font that matches "pattern" that is as close as
\r
3346 * possible to the targetPxlSize. Prefer fonts that are k
\r
3347 * pixels smaller to fonts that are k pixels larger. The
\r
3348 * pattern must be in the X Consortium standard format,
\r
3349 * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
\r
3350 * The return value should be freed with XtFree when no
\r
3353 char *FindFont(pattern, targetPxlSize)
\r
3355 int targetPxlSize;
\r
3357 char **fonts, *p, *best, *scalable, *scalableTail;
\r
3358 int i, j, nfonts, minerr, err, pxlSize;
\r
3361 char **missing_list;
\r
3362 int missing_count;
\r
3363 char *def_string, *base_fnt_lst, strInt[3];
\r
3365 XFontStruct **fnt_list;
\r
3367 base_fnt_lst = calloc(1, strlen(pattern) + 3);
\r
3368 sprintf(strInt, "%d", targetPxlSize);
\r
3369 p = strstr(pattern, "--");
\r
3370 strncpy(base_fnt_lst, pattern, p - pattern + 2);
\r
3371 strcat(base_fnt_lst, strInt);
\r
3372 strcat(base_fnt_lst, strchr(p + 2, '-'));
\r
3374 if ((fntSet = XCreateFontSet(xDisplay,
\r
3378 &def_string)) == NULL) {
\r
3380 fprintf(stderr, _("Unable to create font set.\n"));
\r
3384 nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
\r
3386 fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
\r
3388 fprintf(stderr, _("%s: no fonts match pattern %s\n"),
\r
3389 programName, pattern);
\r
3397 for (i=0; i<nfonts; i++) {
\r
3400 if (*p != '-') continue;
\r
3402 if (*p == NULLCHAR) break;
\r
3403 if (*p++ == '-') j++;
\r
3405 if (j < 7) continue;
\r
3406 pxlSize = atoi(p);
\r
3407 if (pxlSize == 0) {
\r
3408 scalable = fonts[i];
\r
3411 err = pxlSize - targetPxlSize;
\r
3412 if (Abs(err) < Abs(minerr) ||
\r
3413 (minerr > 0 && err < 0 && -err == minerr)) {
\r
3419 if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
\r
3420 /* If the error is too big and there is a scalable font,
\r
3421 use the scalable font. */
\r
3422 int headlen = scalableTail - scalable;
\r
3423 p = (char *) XtMalloc(strlen(scalable) + 10);
\r
3424 while (isdigit(*scalableTail)) scalableTail++;
\r
3425 sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
\r
3427 p = (char *) XtMalloc(strlen(best) + 1);
\r
3430 if (appData.debugMode) {
\r
3431 fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"),
\r
3432 pattern, targetPxlSize, p);
\r
3435 if (missing_count > 0)
\r
3436 XFreeStringList(missing_list);
\r
3437 XFreeFontSet(xDisplay, fntSet);
\r
3439 XFreeFontNames(fonts);
\r
3446 XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
\r
3447 | GCBackground | GCFunction | GCPlaneMask;
\r
3448 XGCValues gc_values;
\r
3449 GC copyInvertedGC;
\r
3451 gc_values.plane_mask = AllPlanes;
\r
3452 gc_values.line_width = lineGap;
\r
3453 gc_values.line_style = LineSolid;
\r
3454 gc_values.function = GXcopy;
\r
3456 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3457 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3458 lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3460 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3461 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3462 coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3463 XSetFont(xDisplay, coordGC, coordFontID);
\r
3465 // [HGM] make font for holdings counts (white on black0
\r
3466 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3467 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3468 countGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3469 XSetFont(xDisplay, countGC, countFontID);
\r
3471 if (appData.monoMode) {
\r
3472 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3473 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3474 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3476 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3477 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3478 lightSquareGC = wbPieceGC
\r
3479 = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3481 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3482 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3483 darkSquareGC = bwPieceGC
\r
3484 = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3486 if (DefaultDepth(xDisplay, xScreen) == 1) {
\r
3487 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
\r
3488 gc_values.function = GXcopyInverted;
\r
3489 copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3490 gc_values.function = GXcopy;
\r
3491 if (XBlackPixel(xDisplay, xScreen) == 1) {
\r
3492 bwPieceGC = darkSquareGC;
\r
3493 wbPieceGC = copyInvertedGC;
\r
3495 bwPieceGC = copyInvertedGC;
\r
3496 wbPieceGC = lightSquareGC;
\r
3500 gc_values.foreground = highlightSquareColor;
\r
3501 gc_values.background = highlightSquareColor;
\r
3502 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3504 gc_values.foreground = premoveHighlightColor;
\r
3505 gc_values.background = premoveHighlightColor;
\r
3506 prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3508 gc_values.foreground = lightSquareColor;
\r
3509 gc_values.background = darkSquareColor;
\r
3510 lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3512 gc_values.foreground = darkSquareColor;
\r
3513 gc_values.background = lightSquareColor;
\r
3514 darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3516 gc_values.foreground = jailSquareColor;
\r
3517 gc_values.background = jailSquareColor;
\r
3518 jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3520 gc_values.foreground = whitePieceColor;
\r
3521 gc_values.background = darkSquareColor;
\r
3522 wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3524 gc_values.foreground = whitePieceColor;
\r
3525 gc_values.background = lightSquareColor;
\r
3526 wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3528 gc_values.foreground = whitePieceColor;
\r
3529 gc_values.background = jailSquareColor;
\r
3530 wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3532 gc_values.foreground = blackPieceColor;
\r
3533 gc_values.background = darkSquareColor;
\r
3534 bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3536 gc_values.foreground = blackPieceColor;
\r
3537 gc_values.background = lightSquareColor;
\r
3538 blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3540 gc_values.foreground = blackPieceColor;
\r
3541 gc_values.background = jailSquareColor;
\r
3542 bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3546 void loadXIM(xim, xmask, filename, dest, mask)
\r
3553 int x, y, w, h, p;
\r
3559 fp = fopen(filename, "rb");
\r
3561 fprintf(stderr, _("%s: error loading XIM!\n"), programName);
\r
3568 for (y=0; y<h; ++y) {
\r
3569 for (x=0; x<h; ++x) {
\r
3574 XPutPixel(xim, x, y, blackPieceColor);
\r
3576 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
\r
3579 XPutPixel(xim, x, y, darkSquareColor);
\r
3581 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
\r
3584 XPutPixel(xim, x, y, whitePieceColor);
\r
3586 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
\r
3589 XPutPixel(xim, x, y, lightSquareColor);
\r
3591 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
\r
3597 /* create Pixmap of piece */
\r
3598 *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3599 w, h, xim->depth);
\r
3600 XPutImage(xDisplay, *dest, lightSquareGC, xim,
\r
3601 0, 0, 0, 0, w, h);
\r
3603 /* create Pixmap of clipmask
\r
3604 Note: We assume the white/black pieces have the same
\r
3605 outline, so we make only 6 masks. This is okay
\r
3606 since the XPM clipmask routines do the same. */
\r
3608 temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3609 w, h, xim->depth);
\r
3610 XPutImage(xDisplay, temp, lightSquareGC, xmask,
\r
3611 0, 0, 0, 0, w, h);
\r
3613 /* now create the 1-bit version */
\r
3614 *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3617 values.foreground = 1;
\r
3618 values.background = 0;
\r
3620 /* Don't use XtGetGC, not read only */
\r
3621 maskGC = XCreateGC(xDisplay, *mask,
\r
3622 GCForeground | GCBackground, &values);
\r
3623 XCopyPlane(xDisplay, temp, *mask, maskGC,
\r
3624 0, 0, squareSize, squareSize, 0, 0, 1);
\r
3625 XFreePixmap(xDisplay, temp);
\r
3629 void CreateXIMPieces()
\r
3632 char buf[MSG_SIZ];
\r
3634 static char *ximkind[] = { "ll", "ld", "dl", "dd" };
\r
3639 /* The XSynchronize calls were copied from CreatePieces.
\r
3640 Not sure if needed, but can't hurt */
\r
3641 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3644 /* temp needed by loadXIM() */
\r
3645 ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3646 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3648 if (strlen(appData.pixmapDirectory) == 0) {
\r
3652 if (appData.monoMode) {
\r
3653 DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
\r
3657 fprintf(stderr, _("\nLoading XIMs...\n"));
\r
3659 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3660 fprintf(stderr, "%d", piece+1);
\r
3661 for (kind=0; kind<4; kind++) {
\r
3662 fprintf(stderr, ".");
\r
3663 sprintf(buf, "%s/%c%s%u.xim",
\r
3664 ExpandPathName(appData.pixmapDirectory),
\r
3665 ToLower(PieceToChar((ChessSquare)piece)),
\r
3666 ximkind[kind], ss);
\r
3667 ximPieceBitmap[kind][piece] =
\r
3668 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3669 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3670 if (appData.debugMode)
\r
3671 fprintf(stderr, _("(File:%s:) "), buf);
\r
3672 loadXIM(ximPieceBitmap[kind][piece],
\r
3674 &(xpmPieceBitmap[kind][piece]),
\r
3675 &(ximMaskPm[piece%(int)BlackPawn]));
\r
3677 fprintf(stderr," ");
\r
3679 /* Load light and dark squares */
\r
3680 /* If the LSQ and DSQ pieces don't exist, we will
\r
3681 draw them with solid squares. */
\r
3682 sprintf(buf, "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
\r
3683 if (access(buf, 0) != 0) {
\r
3687 fprintf(stderr, _("light square "));
\r
3689 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3690 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3691 if (appData.debugMode)
\r
3692 fprintf(stderr, _("(File:%s:) "), buf);
\r
3694 loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
\r
3695 fprintf(stderr, _("dark square "));
\r
3696 sprintf(buf, "%s/dsq%u.xim",
\r
3697 ExpandPathName(appData.pixmapDirectory), ss);
\r
3698 if (appData.debugMode)
\r
3699 fprintf(stderr, _("(File:%s:) "), buf);
\r
3701 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3702 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3703 loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
\r
3704 xpmJailSquare = xpmLightSquare;
\r
3706 fprintf(stderr, _("Done.\n"));
\r
3708 XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
\r
3712 void CreateXPMPieces()
\r
3714 int piece, kind, r;
\r
3715 char buf[MSG_SIZ];
\r
3716 u_int ss = squareSize;
\r
3717 XpmAttributes attr;
\r
3718 static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
\r
3719 XpmColorSymbol symbols[4];
\r
3722 /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
\r
3723 if (appData.debugMode) {
\r
3724 fprintf(stderr, "XPM Library Version: %d.%d%c\n",
\r
3725 XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
\r
3729 /* The XSynchronize calls were copied from CreatePieces.
\r
3730 Not sure if needed, but can't hurt */
\r
3731 XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
\r
3733 /* Setup translations so piece colors match square colors */
\r
3734 symbols[0].name = "light_piece";
\r
3735 symbols[0].value = appData.whitePieceColor;
\r
3736 symbols[1].name = "dark_piece";
\r
3737 symbols[1].value = appData.blackPieceColor;
\r
3738 symbols[2].name = "light_square";
\r
3739 symbols[2].value = appData.lightSquareColor;
\r
3740 symbols[3].name = "dark_square";
\r
3741 symbols[3].value = appData.darkSquareColor;
\r
3743 attr.valuemask = XpmColorSymbols;
\r
3744 attr.colorsymbols = symbols;
\r
3745 attr.numsymbols = 4;
\r
3747 if (appData.monoMode) {
\r
3748 DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
\r
3752 if (strlen(appData.pixmapDirectory) == 0) {
\r
3753 XpmPieces* pieces = builtInXpms;
\r
3756 while (pieces->size != squareSize && pieces->size) pieces++;
\r
3757 if (!pieces->size) {
\r
3758 fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
\r
3761 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3762 for (kind=0; kind<4; kind++) {
\r
3764 if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
\r
3765 pieces->xpm[piece][kind],
\r
3766 &(xpmPieceBitmap[kind][piece]),
\r
3767 NULL, &attr)) != 0) {
\r
3768 fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
\r
3775 xpmJailSquare = xpmLightSquare;
\r
3779 fprintf(stderr, _("\nLoading XPMs...\n"));
\r
3782 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3783 fprintf(stderr, "%d ", piece+1);
\r
3784 for (kind=0; kind<4; kind++) {
\r
3785 sprintf(buf, "%s/%c%s%u.xpm",
\r
3786 ExpandPathName(appData.pixmapDirectory),
\r
3787 ToLower(PieceToChar((ChessSquare)piece)),
\r
3788 xpmkind[kind], ss);
\r
3789 if (appData.debugMode) {
\r
3790 fprintf(stderr, _("(File:%s:) "), buf);
\r
3792 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3793 &(xpmPieceBitmap[kind][piece]),
\r
3794 NULL, &attr)) != 0) {
\r
3795 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
\r
3801 /* Load light and dark squares */
\r
3802 /* If the LSQ and DSQ pieces don't exist, we will
\r
3803 draw them with solid squares. */
\r
3804 fprintf(stderr, _("light square "));
\r
3805 sprintf(buf, "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
\r
3806 if (access(buf, 0) != 0) {
\r
3810 if (appData.debugMode)
\r
3811 fprintf(stderr, _("(File:%s:) "), buf);
\r
3813 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3814 &xpmLightSquare, NULL, &attr)) != 0) {
\r
3815 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
\r
3818 fprintf(stderr, _("dark square "));
\r
3819 sprintf(buf, "%s/dsq%u.xpm",
\r
3820 ExpandPathName(appData.pixmapDirectory), ss);
\r
3821 if (appData.debugMode) {
\r
3822 fprintf(stderr, _("(File:%s:) "), buf);
\r
3824 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3825 &xpmDarkSquare, NULL, &attr)) != 0) {
\r
3826 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
\r
3830 xpmJailSquare = xpmLightSquare;
\r
3831 fprintf(stderr, _("Done.\n"));
\r
3833 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3836 #endif /* HAVE_LIBXPM */
\r
3839 /* No built-in bitmaps */
\r
3840 void CreatePieces()
\r
3843 char buf[MSG_SIZ];
\r
3844 u_int ss = squareSize;
\r
3846 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3849 for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
\r
3850 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3851 sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
\r
3852 ss, kind == SOLID ? 's' : 'o');
\r
3853 ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);
\r
3857 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3861 /* With built-in bitmaps */
\r
3862 void CreatePieces()
\r
3864 BuiltInBits* bib = builtInBits;
\r
3866 char buf[MSG_SIZ];
\r
3867 u_int ss = squareSize;
\r
3869 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3872 while (bib->squareSize != ss && bib->squareSize != 0) bib++;
\r
3874 for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
\r
3875 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3876 sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
\r
3877 ss, kind == SOLID ? 's' : 'o');
\r
3878 ReadBitmap(&pieceBitmap[kind][piece], buf,
\r
3879 bib->bits[kind][piece], ss, ss);
\r
3883 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3888 void ReadBitmap(pm, name, bits, wreq, hreq)
\r
3891 unsigned char bits[];
\r
3897 char msg[MSG_SIZ], fullname[MSG_SIZ];
\r
3899 if (*appData.bitmapDirectory != NULLCHAR) {
\r
3900 strcpy(fullname, appData.bitmapDirectory);
\r
3901 strcat(fullname, "/");
\r
3902 strcat(fullname, name);
\r
3903 errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
\r
3904 &w, &h, pm, &x_hot, &y_hot);
\r
3905 if (errcode != BitmapSuccess) {
\r
3906 switch (errcode) {
\r
3907 case BitmapOpenFailed:
\r
3908 sprintf(msg, _("Can't open bitmap file %s"), fullname);
\r
3910 case BitmapFileInvalid:
\r
3911 sprintf(msg, _("Invalid bitmap in file %s"), fullname);
\r
3913 case BitmapNoMemory:
\r
3914 sprintf(msg, _("Ran out of memory reading bitmap file %s"),
\r
3918 sprintf(msg, _("Unknown XReadBitmapFile error %d on file %s"),
\r
3919 errcode, fullname);
\r
3922 fprintf(stderr, _("%s: %s...using built-in\n"),
\r
3923 programName, msg);
\r
3924 } else if (w != wreq || h != hreq) {
\r
3926 _("%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n"),
\r
3927 programName, fullname, w, h, wreq, hreq);
\r
3932 if (bits == NULL) {
\r
3934 fprintf(stderr, _("%s: No built-in bitmap for %s; giving up\n"),
\r
3935 programName, name);
\r
3938 ; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
\r
3940 *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
\r
3949 if (lineGap == 0) return;
\r
3951 /* [HR] Split this into 2 loops for non-square boards. */
\r
3953 for (i = 0; i < BOARD_HEIGHT + 1; i++) {
\r
3954 gridSegments[i].x1 = 0;
\r
3955 gridSegments[i].x2 =
\r
3956 lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
3957 gridSegments[i].y1 = gridSegments[i].y2
\r
3958 = lineGap / 2 + (i * (squareSize + lineGap));
\r
3961 for (j = 0; j < BOARD_WIDTH + 1; j++) {
\r
3962 gridSegments[j + i].y1 = 0;
\r
3963 gridSegments[j + i].y2 =
\r
3964 lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
3965 gridSegments[j + i].x1 = gridSegments[j + i].x2
\r
3966 = lineGap / 2 + (j * (squareSize + lineGap));
\r
3970 static void MenuBarSelect(w, addr, index)
\r
3975 XtActionProc proc = (XtActionProc) addr;
\r
3977 (proc)(NULL, NULL, NULL, NULL);
\r
3980 void CreateMenuBarPopup(parent, name, mb)
\r
3986 Widget menu, entry;
\r
3990 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
\r
3993 XtSetArg(args[j], XtNleftMargin, 20); j++;
\r
3994 XtSetArg(args[j], XtNrightMargin, 20); j++;
\r
3996 while (mi->string != NULL) {
\r
3997 if (strcmp(mi->string, "----") == 0) {
\r
3998 entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
\r
4001 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
\r
4002 entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
\r
4004 XtAddCallback(entry, XtNcallback,
\r
4005 (XtCallbackProc) MenuBarSelect,
\r
4006 (caddr_t) mi->proc);
\r
4012 Widget CreateMenuBar(mb)
\r
4016 Widget anchor, menuBar;
\r
4018 char menuName[MSG_SIZ];
\r
4021 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
\r
4022 XtSetArg(args[j], XtNvSpace, 0); j++;
\r
4023 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4024 menuBar = XtCreateWidget("menuBar", boxWidgetClass,
\r
4025 formWidget, args, j);
\r
4027 while (mb->name != NULL) {
\r
4028 strcpy(menuName, "menu");
\r
4029 strcat(menuName, mb->name);
\r
4031 XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;
\r
4033 char shortName[2];
\r
4034 shortName[0] = _(mb->name)[0];
\r
4035 shortName[1] = NULLCHAR;
\r
4036 XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
\r
4039 XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++;
\r
4042 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4043 anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
\r
4044 menuBar, args, j);
\r
4045 CreateMenuBarPopup(menuBar, menuName, mb);
\r
4051 Widget CreateButtonBar(mi)
\r
4055 Widget button, buttonBar;
\r
4059 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
\r
4061 XtSetArg(args[j], XtNhSpace, 0); j++;
\r
4063 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4064 XtSetArg(args[j], XtNvSpace, 0); j++;
\r
4065 buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
\r
4066 formWidget, args, j);
\r
4068 while (mi->string != NULL) {
\r
4071 XtSetArg(args[j], XtNinternalWidth, 2); j++;
\r
4072 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4074 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
\r
4075 button = XtCreateManagedWidget(mi->string, commandWidgetClass,
\r
4076 buttonBar, args, j);
\r
4077 XtAddCallback(button, XtNcallback,
\r
4078 (XtCallbackProc) MenuBarSelect,
\r
4079 (caddr_t) mi->proc);
\r
4086 CreatePieceMenu(name, color)
\r
4091 Widget entry, menu;
\r
4093 ChessSquare selection;
\r
4095 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
\r
4096 boardWidget, args, 0);
\r
4098 for (i = 0; i < PIECE_MENU_SIZE; i++) {
\r
4099 String item = pieceMenuStrings[color][i];
\r
4101 if (strcmp(item, "----") == 0) {
\r
4102 entry = XtCreateManagedWidget(item, smeLineObjectClass,
\r
4105 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
\r
4106 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
\r
4108 selection = pieceMenuTranslation[color][i];
\r
4109 XtAddCallback(entry, XtNcallback,
\r
4110 (XtCallbackProc) PieceMenuSelect,
\r
4111 (caddr_t) selection);
\r
4112 if (selection == WhitePawn || selection == BlackPawn) {
\r
4113 XtSetArg(args[0], XtNpopupOnEntry, entry);
\r
4114 XtSetValues(menu, args, 1);
\r
4122 CreatePieceMenus()
\r
4127 ChessSquare selection;
\r
4129 whitePieceMenu = CreatePieceMenu("menuW", 0);
\r
4130 blackPieceMenu = CreatePieceMenu("menuB", 1);
\r
4132 XtRegisterGrabAction(PieceMenuPopup, True,
\r
4133 (unsigned)(ButtonPressMask|ButtonReleaseMask),
\r
4134 GrabModeAsync, GrabModeAsync);
\r
4136 XtSetArg(args[0], XtNlabel, _("Drop"));
\r
4137 dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
\r
4138 boardWidget, args, 1);
\r
4139 for (i = 0; i < DROP_MENU_SIZE; i++) {
\r
4140 String item = dropMenuStrings[i];
\r
4142 if (strcmp(item, "----") == 0) {
\r
4143 entry = XtCreateManagedWidget(item, smeLineObjectClass,
\r
4144 dropMenu, NULL, 0);
\r
4146 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
\r
4147 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
\r
4148 dropMenu, args, 1);
\r
4149 selection = dropMenuTranslation[i];
\r
4150 XtAddCallback(entry, XtNcallback,
\r
4151 (XtCallbackProc) DropMenuSelect,
\r
4152 (caddr_t) selection);
\r
4157 void SetupDropMenu()
\r
4165 for (i=0; i<sizeof(dmEnables)/sizeof(DropMenuEnables); i++) {
\r
4166 entry = XtNameToWidget(dropMenu, dmEnables[i].widget);
\r
4167 p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,
\r
4168 dmEnables[i].piece);
\r
4169 XtSetSensitive(entry, p != NULL || !appData.testLegality
\r
4170 /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse
\r
4171 && !appData.icsActive));
\r
4173 while (p && *p++ == dmEnables[i].piece) count++;
\r
4174 sprintf(label, "%s %d", dmEnables[i].widget, count);
\r
4176 XtSetArg(args[j], XtNlabel, label); j++;
\r
4177 XtSetValues(entry, args, j);
\r
4181 void PieceMenuPopup(w, event, params, num_params)
\r
4185 Cardinal *num_params;
\r
4188 if (event->type != ButtonPress) return;
\r
4189 if (errorUp) ErrorPopDown();
\r
4190 switch (gameMode) {
\r
4191 case EditPosition:
\r
4192 case IcsExamining:
\r
4193 whichMenu = params[0];
\r
4195 case IcsPlayingWhite:
\r
4196 case IcsPlayingBlack:
\r
4198 case MachinePlaysWhite:
\r
4199 case MachinePlaysBlack:
\r
4200 if (appData.testLegality &&
\r
4201 gameInfo.variant != VariantBughouse &&
\r
4202 gameInfo.variant != VariantCrazyhouse) return;
\r
4204 whichMenu = "menuD";
\r
4210 if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||
\r
4211 ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {
\r
4212 pmFromX = pmFromY = -1;
\r
4216 pmFromX = BOARD_WIDTH - 1 - pmFromX;
\r
4218 pmFromY = BOARD_HEIGHT - 1 - pmFromY;
\r
4220 XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
\r
4223 static void PieceMenuSelect(w, piece, junk)
\r
4225 ChessSquare piece;
\r
4228 if (pmFromX < 0 || pmFromY < 0) return;
\r
4229 EditPositionMenuEvent(piece, pmFromX, pmFromY);
\r
4232 static void DropMenuSelect(w, piece, junk)
\r
4234 ChessSquare piece;
\r
4237 if (pmFromX < 0 || pmFromY < 0) return;
\r
4238 DropMenuEvent(piece, pmFromX, pmFromY);
\r
4241 void WhiteClock(w, event, prms, nprms)
\r
4247 if (gameMode == EditPosition || gameMode == IcsExamining) {
\r
4248 SetWhiteToPlayEvent();
\r
4249 } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
\r
4254 void BlackClock(w, event, prms, nprms)
\r
4260 if (gameMode == EditPosition || gameMode == IcsExamining) {
\r
4261 SetBlackToPlayEvent();
\r
4262 } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
\r
4269 * If the user selects on a border boundary, return -1; if off the board,
\r
4270 * return -2. Otherwise map the event coordinate to the square.
\r
4272 int EventToSquare(x, limit)
\r
4280 if ((x % (squareSize + lineGap)) >= squareSize)
\r
4282 x /= (squareSize + lineGap);
\r
4288 static void do_flash_delay(msec)
\r
4289 unsigned long msec;
\r
4294 static void drawHighlight(file, rank, gc)
\r
4300 if (lineGap == 0 || appData.blindfold) return;
\r
4303 x = lineGap/2 + ((BOARD_WIDTH-1)-file) *
\r
4304 (squareSize + lineGap);
\r
4305 y = lineGap/2 + rank * (squareSize + lineGap);
\r
4307 x = lineGap/2 + file * (squareSize + lineGap);
\r
4308 y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) *
\r
4309 (squareSize + lineGap);
\r
4312 XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
\r
4313 squareSize+lineGap, squareSize+lineGap);
\r
4316 int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
\r
4317 int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1;
\r
4320 SetHighlights(fromX, fromY, toX, toY)
\r
4321 int fromX, fromY, toX, toY;
\r
4323 if (hi1X != fromX || hi1Y != fromY) {
\r
4324 if (hi1X >= 0 && hi1Y >= 0) {
\r
4325 drawHighlight(hi1X, hi1Y, lineGC);
\r
4327 if (fromX >= 0 && fromY >= 0) {
\r
4328 drawHighlight(fromX, fromY, highlineGC);
\r
4331 if (hi2X != toX || hi2Y != toY) {
\r
4332 if (hi2X >= 0 && hi2Y >= 0) {
\r
4333 drawHighlight(hi2X, hi2Y, lineGC);
\r
4335 if (toX >= 0 && toY >= 0) {
\r
4336 drawHighlight(toX, toY, highlineGC);
\r
4348 SetHighlights(-1, -1, -1, -1);
\r
4353 SetPremoveHighlights(fromX, fromY, toX, toY)
\r
4354 int fromX, fromY, toX, toY;
\r
4356 if (pm1X != fromX || pm1Y != fromY) {
\r
4357 if (pm1X >= 0 && pm1Y >= 0) {
\r
4358 drawHighlight(pm1X, pm1Y, lineGC);
\r
4360 if (fromX >= 0 && fromY >= 0) {
\r
4361 drawHighlight(fromX, fromY, prelineGC);
\r
4364 if (pm2X != toX || pm2Y != toY) {
\r
4365 if (pm2X >= 0 && pm2Y >= 0) {
\r
4366 drawHighlight(pm2X, pm2Y, lineGC);
\r
4368 if (toX >= 0 && toY >= 0) {
\r
4369 drawHighlight(toX, toY, prelineGC);
\r
4379 ClearPremoveHighlights()
\r
4381 SetPremoveHighlights(-1, -1, -1, -1);
\r
4384 static void BlankSquare(x, y, color, piece, dest)
\r
4386 ChessSquare piece;
\r
4389 if (useImages && useImageSqs) {
\r
4392 case 1: /* light */
\r
4393 pm = xpmLightSquare;
\r
4395 case 0: /* dark */
\r
4396 pm = xpmDarkSquare;
\r
4398 case 2: /* neutral */
\r
4400 pm = xpmJailSquare;
\r
4403 XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
\r
4404 squareSize, squareSize, x, y);
\r
4408 case 1: /* light */
\r
4409 gc = lightSquareGC;
\r
4411 case 0: /* dark */
\r
4412 gc = darkSquareGC;
\r
4414 case 2: /* neutral */
\r
4416 gc = jailSquareGC;
\r
4419 XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize);
\r
4424 I split out the routines to draw a piece so that I could
\r
4425 make a generic flash routine.
\r
4427 static void monoDrawPiece_1bit(piece, square_color, x, y, dest)
\r
4428 ChessSquare piece;
\r
4429 int square_color, x, y;
\r
4432 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
\r
4433 switch (square_color) {
\r
4434 case 1: /* light */
\r
4435 case 2: /* neutral */
\r
4437 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
\r
4438 ? *pieceToOutline(piece)
\r
4439 : *pieceToSolid(piece),
\r
4440 dest, bwPieceGC, 0, 0,
\r
4441 squareSize, squareSize, x, y);
\r
4443 case 0: /* dark */
\r
4444 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
\r
4445 ? *pieceToSolid(piece)
\r
4446 : *pieceToOutline(piece),
\r
4447 dest, wbPieceGC, 0, 0,
\r
4448 squareSize, squareSize, x, y);
\r
4453 static void monoDrawPiece(piece, square_color, x, y, dest)
\r
4454 ChessSquare piece;
\r
4455 int square_color, x, y;
\r
4458 switch (square_color) {
\r
4459 case 1: /* light */
\r
4460 case 2: /* neutral */
\r
4462 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
\r
4463 ? *pieceToOutline(piece)
\r
4464 : *pieceToSolid(piece),
\r
4465 dest, bwPieceGC, 0, 0,
\r
4466 squareSize, squareSize, x, y, 1);
\r
4468 case 0: /* dark */
\r
4469 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
\r
4470 ? *pieceToSolid(piece)
\r
4471 : *pieceToOutline(piece),
\r
4472 dest, wbPieceGC, 0, 0,
\r
4473 squareSize, squareSize, x, y, 1);
\r
4478 static void colorDrawPiece(piece, square_color, x, y, dest)
\r
4479 ChessSquare piece;
\r
4480 int square_color, x, y;
\r
4483 if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
\r
4484 switch (square_color) {
\r
4485 case 1: /* light */
\r
4486 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4487 dest, (int) piece < (int) BlackPawn
\r
4488 ? wlPieceGC : blPieceGC, 0, 0,
\r
4489 squareSize, squareSize, x, y, 1);
\r
4491 case 0: /* dark */
\r
4492 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4493 dest, (int) piece < (int) BlackPawn
\r
4494 ? wdPieceGC : bdPieceGC, 0, 0,
\r
4495 squareSize, squareSize, x, y, 1);
\r
4497 case 2: /* neutral */
\r
4499 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4500 dest, (int) piece < (int) BlackPawn
\r
4501 ? wjPieceGC : bjPieceGC, 0, 0,
\r
4502 squareSize, squareSize, x, y, 1);
\r
4507 static void colorDrawPieceImage(piece, square_color, x, y, dest)
\r
4508 ChessSquare piece;
\r
4509 int square_color, x, y;
\r
4514 switch (square_color) {
\r
4515 case 1: /* light */
\r
4516 case 2: /* neutral */
\r
4518 if ((int)piece < (int) BlackPawn) {
\r
4522 piece -= BlackPawn;
\r
4525 case 0: /* dark */
\r
4526 if ((int)piece < (int) BlackPawn) {
\r
4530 piece -= BlackPawn;
\r
4534 XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
\r
4535 dest, wlPieceGC, 0, 0,
\r
4536 squareSize, squareSize, x, y);
\r
4539 typedef void (*DrawFunc)();
\r
4541 DrawFunc ChooseDrawFunc()
\r
4543 if (appData.monoMode) {
\r
4544 if (DefaultDepth(xDisplay, xScreen) == 1) {
\r
4545 return monoDrawPiece_1bit;
\r
4547 return monoDrawPiece;
\r
4551 return colorDrawPieceImage;
\r
4553 return colorDrawPiece;
\r
4557 /* [HR] determine square color depending on chess variant. */
\r
4558 static int SquareColor(row, column)
\r
4563 if (gameInfo.variant == VariantXiangqi) {
\r
4564 if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {
\r
4566 } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {
\r
4568 } else if (row <= 4) {
\r
4574 square_color = ((column + row) % 2) == 1;
\r
4577 /* [hgm] holdings: next line makes all holdings squares light */
\r
4578 if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1;
\r
4580 return square_color;
\r
4583 void DrawSquare(row, column, piece, do_flash)
\r
4584 int row, column, do_flash;
\r
4585 ChessSquare piece;
\r
4587 int square_color, x, y, direction, font_ascent, font_descent;
\r
4590 XCharStruct overall;
\r
4591 DrawFunc drawfunc;
\r
4594 if(gameInfo.variant == VariantShogi) { // [HGM] shogi: in shogi Q is used for Lance
\r
4595 if(piece == WhiteQueen) piece = WhiteLance; else
\r
4596 if(piece == BlackQueen) piece = BlackLance;
\r
4599 else if(gameInfo.variant == VariantGothic) { // [HGM] shogi: in Gothic Chancelor has alternative look
\r
4600 if(piece == WhiteMarshall) piece = WhiteSilver; else
\r
4601 if(piece == BlackMarshall) piece = BlackSilver;
\r
4605 /* Calculate delay in milliseconds (2-delays per complete flash) */
\r
4606 flash_delay = 500 / appData.flashRate;
\r
4609 x = lineGap + ((BOARD_WIDTH-1)-column) *
\r
4610 (squareSize + lineGap);
\r
4611 y = lineGap + row * (squareSize + lineGap);
\r
4613 x = lineGap + column * (squareSize + lineGap);
\r
4614 y = lineGap + ((BOARD_HEIGHT-1)-row) *
\r
4615 (squareSize + lineGap);
\r
4618 square_color = SquareColor(row, column);
\r
4620 if ( // [HGM] holdings: blank out area between board and holdings
\r
4621 column == BOARD_LEFT-1 || column == BOARD_RGHT
\r
4622 || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)
\r
4623 || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {
\r
4624 BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
\r
4626 // [HGM] print piece counts next to holdings
\r
4627 string[1] = NULLCHAR;
\r
4628 if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) {
\r
4629 string[0] = '0' + piece;
\r
4630 XTextExtents(countFontStruct, string, 1, &direction,
\r
4631 &font_ascent, &font_descent, &overall);
\r
4632 if (appData.monoMode) {
\r
4633 XDrawImageString(xDisplay, xBoardWindow, countGC,
\r
4634 x + squareSize - overall.width - 2,
\r
4635 y + font_ascent + 1, string, 1);
\r
4637 XDrawString(xDisplay, xBoardWindow, countGC,
\r
4638 x + squareSize - overall.width - 2,
\r
4639 y + font_ascent + 1, string, 1);
\r
4642 if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) {
\r
4643 string[0] = '0' + piece;
\r
4644 XTextExtents(countFontStruct, string, 1, &direction,
\r
4645 &font_ascent, &font_descent, &overall);
\r
4646 if (appData.monoMode) {
\r
4647 XDrawImageString(xDisplay, xBoardWindow, countGC,
\r
4648 x + 2, y + font_ascent + 1, string, 1);
\r
4650 XDrawString(xDisplay, xBoardWindow, countGC,
\r
4651 x + 2, y + font_ascent + 1, string, 1);
\r
4655 if (piece == EmptySquare || appData.blindfold) {
\r
4656 BlankSquare(x, y, square_color, piece, xBoardWindow);
\r
4658 drawfunc = ChooseDrawFunc();
\r
4659 if (do_flash && appData.flashCount > 0) {
\r
4660 for (i=0; i<appData.flashCount; ++i) {
\r
4662 drawfunc(piece, square_color, x, y, xBoardWindow);
\r
4663 XSync(xDisplay, False);
\r
4664 do_flash_delay(flash_delay);
\r
4666 BlankSquare(x, y, square_color, piece, xBoardWindow);
\r
4667 XSync(xDisplay, False);
\r
4668 do_flash_delay(flash_delay);
\r
4671 drawfunc(piece, square_color, x, y, xBoardWindow);
\r
4675 string[1] = NULLCHAR;
\r
4676 if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)
\r
4677 && column >= BOARD_LEFT && column < BOARD_RGHT) {
\r
4678 string[0] = 'a' + column - BOARD_LEFT;
\r
4679 XTextExtents(coordFontStruct, string, 1, &direction,
\r
4680 &font_ascent, &font_descent, &overall);
\r
4681 if (appData.monoMode) {
\r
4682 XDrawImageString(xDisplay, xBoardWindow, coordGC,
\r
4683 x + squareSize - overall.width - 2,
\r
4684 y + squareSize - font_descent - 1, string, 1);
\r
4686 XDrawString(xDisplay, xBoardWindow, coordGC,
\r
4687 x + squareSize - overall.width - 2,
\r
4688 y + squareSize - font_descent - 1, string, 1);
\r
4691 if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) {
\r
4692 string[0] = ONE + row;
\r
4693 XTextExtents(coordFontStruct, string, 1, &direction,
\r
4694 &font_ascent, &font_descent, &overall);
\r
4695 if (appData.monoMode) {
\r
4696 XDrawImageString(xDisplay, xBoardWindow, coordGC,
\r
4697 x + 2, y + font_ascent + 1, string, 1);
\r
4699 XDrawString(xDisplay, xBoardWindow, coordGC,
\r
4700 x + 2, y + font_ascent + 1, string, 1);
\r
4706 /* Why is this needed on some versions of X? */
\r
4707 void EventProc(widget, unused, event)
\r
4712 if (!XtIsRealized(widget))
\r
4715 switch (event->type) {
\r
4717 if (event->xexpose.count > 0) return; /* no clipping is done */
\r
4718 XDrawPosition(widget, True, NULL);
\r
4726 void DrawPosition(fullRedraw, board)
\r
4727 /*Boolean*/int fullRedraw;
\r
4730 XDrawPosition(boardWidget, fullRedraw, board);
\r
4733 /* Returns 1 if there are "too many" differences between b1 and b2
\r
4734 (i.e. more than 1 move was made) */
\r
4735 static int too_many_diffs(b1, b2)
\r
4741 for (i=0; i<BOARD_HEIGHT; ++i) {
\r
4742 for (j=0; j<BOARD_WIDTH; ++j) {
\r
4743 if (b1[i][j] != b2[i][j]) {
\r
4744 if (++c > 4) /* Castling causes 4 diffs */
\r
4753 /* Matrix describing castling maneuvers */
\r
4754 /* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */
\r
4755 static int castling_matrix[4][5] = {
\r
4756 { 0, 0, 4, 3, 2 }, /* 0-0-0, white */
\r
4757 { 0, 7, 4, 5, 6 }, /* 0-0, white */
\r
4758 { 7, 0, 4, 3, 2 }, /* 0-0-0, black */
\r
4759 { 7, 7, 4, 5, 6 } /* 0-0, black */
\r
4762 /* Checks whether castling occurred. If it did, *rrow and *rcol
\r
4763 are set to the destination (row,col) of the rook that moved.
\r
4765 Returns 1 if castling occurred, 0 if not.
\r
4767 Note: Only handles a max of 1 castling move, so be sure
\r
4768 to call too_many_diffs() first.
\r
4770 static int check_castle_draw(newb, oldb, rrow, rcol)
\r
4777 /* For each type of castling... */
\r
4778 for (i=0; i<4; ++i) {
\r
4779 r = castling_matrix[i];
\r
4781 /* Check the 4 squares involved in the castling move */
\r
4783 for (j=1; j<=4; ++j) {
\r
4784 if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) {
\r
4791 /* All 4 changed, so it must be a castling move */
\r
4800 static int damage[BOARD_SIZE][BOARD_SIZE];
\r
4803 * event handler for redrawing the board
\r
4805 void XDrawPosition(w, repaint, board)
\r
4807 /*Boolean*/int repaint;
\r
4810 int i, j, do_flash;
\r
4811 static int lastFlipView = 0;
\r
4812 static int lastBoardValid = 0;
\r
4813 static Board lastBoard;
\r
4817 if (board == NULL) {
\r
4818 if (!lastBoardValid) return;
\r
4819 board = lastBoard;
\r
4821 if (!lastBoardValid || lastFlipView != flipView) {
\r
4822 XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
\r
4823 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
\r
4828 * It would be simpler to clear the window with XClearWindow()
\r
4829 * but this causes a very distracting flicker.
\r
4832 if (!repaint && lastBoardValid && lastFlipView == flipView) {
\r
4834 /* If too much changes (begin observing new game, etc.), don't
\r
4836 do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
\r
4838 /* Special check for castling so we don't flash both the king
\r
4839 and the rook (just flash the king). */
\r
4841 if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
\r
4842 /* Draw rook with NO flashing. King will be drawn flashing later */
\r
4843 DrawSquare(rrow, rcol, board[rrow][rcol], 0);
\r
4844 lastBoard[rrow][rcol] = board[rrow][rcol];
\r
4848 /* First pass -- Draw (newly) empty squares and repair damage.
\r
4849 This prevents you from having a piece show up twice while it
\r
4850 is flashing on its new square */
\r
4851 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4852 for (j = 0; j < BOARD_WIDTH; j++)
\r
4853 if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
\r
4854 || damage[i][j]) {
\r
4855 DrawSquare(i, j, board[i][j], 0);
\r
4856 damage[i][j] = False;
\r
4859 /* Second pass -- Draw piece(s) in new position and flash them */
\r
4860 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4861 for (j = 0; j < BOARD_WIDTH; j++)
\r
4862 if (board[i][j] != lastBoard[i][j]) {
\r
4863 DrawSquare(i, j, board[i][j], do_flash);
\r
4867 XDrawSegments(xDisplay, xBoardWindow, lineGC,
\r
4868 gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
\r
4870 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4871 for (j = 0; j < BOARD_WIDTH; j++) {
\r
4872 DrawSquare(i, j, board[i][j], 0);
\r
4873 damage[i][j] = False;
\r
4877 CopyBoard(lastBoard, board);
\r
4878 lastBoardValid = 1;
\r
4879 lastFlipView = flipView;
\r
4881 /* Draw highlights */
\r
4882 if (pm1X >= 0 && pm1Y >= 0) {
\r
4883 drawHighlight(pm1X, pm1Y, prelineGC);
\r
4885 if (pm2X >= 0 && pm2Y >= 0) {
\r
4886 drawHighlight(pm2X, pm2Y, prelineGC);
\r
4888 if (hi1X >= 0 && hi1Y >= 0) {
\r
4889 drawHighlight(hi1X, hi1Y, highlineGC);
\r
4891 if (hi2X >= 0 && hi2Y >= 0) {
\r
4892 drawHighlight(hi2X, hi2Y, highlineGC);
\r
4895 /* If piece being dragged around board, must redraw that too */
\r
4898 XSync(xDisplay, False);
\r
4903 * event handler for redrawing the board
\r
4905 void DrawPositionProc(w, event, prms, nprms)
\r
4911 XDrawPosition(w, True, NULL);
\r
4916 * event handler for parsing user moves
\r
4918 // [HGM] This routine will need quite some reworking. Although the backend still supports the old
\r
4919 // way of doing things, by calling UserMoveEvent() to test the legality of the move and then perform
\r
4920 // it at the end, and doing all kind of preliminary tests here (e.g. to weed out self-captures), it
\r
4921 // should be made to use the new way, of calling UserMoveTest early to determine the legality of the
\r
4922 // move, (which will weed out the illegal selfcaptures and moves into the holdings, and flag promotions),
\r
4923 // and at the end FinishMove() to perform the move after optional promotion popups.
\r
4924 // For now I patched it to allow self-capture with King, and suppress clicks between board and holdings.
\r
4925 void HandleUserMove(w, event, prms, nprms)
\r
4932 Boolean saveAnimate;
\r
4933 static int second = 0;
\r
4935 if (w != boardWidget || errorExitStatus != -1) return;
\r
4937 if (event->type == ButtonPress) ErrorPopDown();
\r
4939 if (promotionUp) {
\r
4940 if (event->type == ButtonPress) {
\r
4941 XtPopdown(promotionShell);
\r
4942 XtDestroyWidget(promotionShell);
\r
4943 promotionUp = False;
\r
4944 ClearHighlights();
\r
4945 fromX = fromY = -1;
\r
4951 x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
\r
4952 y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
\r
4953 if (!flipView && y >= 0) {
\r
4954 y = BOARD_HEIGHT - 1 - y;
\r
4956 if (flipView && x >= 0) {
\r
4957 x = BOARD_WIDTH - 1 - x;
\r
4960 /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
\r
4961 if(event->type == ButtonPress
\r
4962 && ( x == BOARD_LEFT-1 || x == BOARD_RGHT
\r
4963 || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize
\r
4964 || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) )
\r
4967 if (fromX == -1) {
\r
4968 if (event->type == ButtonPress) {
\r
4969 /* First square */
\r
4970 if (OKToStartUserMove(x, y)) {
\r
4974 DragPieceBegin(event->xbutton.x, event->xbutton.y);
\r
4975 if (appData.highlightDragging) {
\r
4976 SetHighlights(x, y, -1, -1);
\r
4984 if (event->type == ButtonPress && gameMode != EditPosition &&
\r
4985 x >= 0 && y >= 0) {
\r
4986 ChessSquare fromP;
\r
4989 /* Check if clicking again on the same color piece */
\r
4990 fromP = boards[currentMove][fromY][fromX];
\r
4991 toP = boards[currentMove][y][x];
\r
4992 if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.
\r
4993 WhitePawn <= toP && toP <= WhiteKing) || // For now I made it less critical by exempting King
\r
4994 (BlackPawn <= fromP && fromP < BlackKing && // moves, to not interfere with FRC castlings.
\r
4995 BlackPawn <= toP && toP <= BlackKing)) {
\r
4996 /* Clicked again on same color piece -- changed his mind */
\r
4997 second = (x == fromX && y == fromY);
\r
4998 if (appData.highlightDragging) {
\r
4999 SetHighlights(x, y, -1, -1);
\r
5001 ClearHighlights();
\r
5003 if (OKToStartUserMove(x, y)) {
\r
5006 DragPieceBegin(event->xbutton.x, event->xbutton.y);
\r
5012 if (event->type == ButtonRelease && x == fromX && y == fromY) {
\r
5013 DragPieceEnd(event->xbutton.x, event->xbutton.y);
\r
5014 if (appData.animateDragging) {
\r
5015 /* Undo animation damage if any */
\r
5016 DrawPosition(FALSE, NULL);
\r
5019 /* Second up/down in same square; just abort move */
\r
5021 fromX = fromY = -1;
\r
5022 ClearHighlights();
\r
5024 ClearPremoveHighlights();
\r
5026 /* First upclick in same square; start click-click mode */
\r
5027 SetHighlights(x, y, -1, -1);
\r
5032 /* Completed move */
\r
5035 saveAnimate = appData.animate;
\r
5036 if (event->type == ButtonPress) {
\r
5037 /* Finish clickclick move */
\r
5038 if (appData.animate || appData.highlightLastMove) {
\r
5039 SetHighlights(fromX, fromY, toX, toY);
\r
5041 ClearHighlights();
\r
5044 /* Finish drag move */
\r
5045 if (appData.highlightLastMove) {
\r
5046 SetHighlights(fromX, fromY, toX, toY);
\r
5048 ClearHighlights();
\r
5050 DragPieceEnd(event->xbutton.x, event->xbutton.y);
\r
5051 /* Don't animate move and drag both */
\r
5052 appData.animate = FALSE;
\r
5054 if (IsPromotion(fromX, fromY, toX, toY)) {
\r
5055 if (appData.alwaysPromoteToQueen) {
\r
5056 UserMoveEvent(fromX, fromY, toX, toY, 'q');
\r
5057 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5058 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5059 fromX = fromY = -1;
\r
5061 SetHighlights(fromX, fromY, toX, toY);
\r
5065 UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
\r
5066 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5067 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5068 fromX = fromY = -1;
\r
5070 appData.animate = saveAnimate;
\r
5071 if (appData.animate || appData.animateDragging) {
\r
5072 /* Undo animation damage if needed */
\r
5073 DrawPosition(FALSE, NULL);
\r
5077 void AnimateUserMove (Widget w, XEvent * event,
\r
5078 String * params, Cardinal * nParams)
\r
5080 DragPieceMove(event->xmotion.x, event->xmotion.y);
\r
5083 Widget CommentCreate(name, text, mutable, callback, lines)
\r
5084 char *name, *text;
\r
5085 int /*Boolean*/ mutable;
\r
5086 XtCallbackProc callback;
\r
5090 Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
\r
5091 Dimension bw_width;
\r
5095 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5096 XtGetValues(boardWidget, args, j);
\r
5099 XtSetArg(args[j], XtNresizable, True); j++;
\r
5102 XtCreatePopupShell(name, topLevelShellWidgetClass,
\r
5103 shellWidget, args, j);
\r
5106 XtCreatePopupShell(name, transientShellWidgetClass,
\r
5107 shellWidget, args, j);
\r
5110 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
\r
5111 layoutArgs, XtNumber(layoutArgs));
\r
5113 XtCreateManagedWidget("form", formWidgetClass, layout,
\r
5114 formArgs, XtNumber(formArgs));
\r
5118 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
\r
5119 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
\r
5121 XtSetArg(args[j], XtNstring, text); j++;
\r
5122 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
5123 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5124 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5125 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
5126 XtSetArg(args[j], XtNresizable, True); j++;
\r
5127 XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/
\r
5129 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
\r
5131 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
\r
5132 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
\r
5134 XtSetArg(args[j], XtNautoFill, True); j++;
\r
5135 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
\r
5137 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
\r
5141 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5142 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5143 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5144 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5145 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5147 XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j);
\r
5148 XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
\r
5151 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5152 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
\r
5153 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5154 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5155 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5156 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5158 XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
\r
5159 XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
\r
5162 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5163 XtSetArg(args[j], XtNfromHoriz, b_cancel); j++;
\r
5164 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5165 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5166 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5167 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5169 XtCreateManagedWidget(_("clear"), commandWidgetClass, form, args, j);
\r
5170 XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
\r
5173 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5174 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5175 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5176 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5177 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5179 XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j);
\r
5180 XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
\r
5183 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5184 XtSetArg(args[j], XtNfromHoriz, b_close); j++;
\r
5185 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5186 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5187 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5188 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5190 XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j);
\r
5191 XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
\r
5194 XtRealizeWidget(shell);
\r
5196 if (commentX == -1) {
\r
5199 Dimension pw_height;
\r
5200 Dimension ew_height;
\r
5203 XtSetArg(args[j], XtNheight, &ew_height); j++;
\r
5204 XtGetValues(edit, args, j);
\r
5207 XtSetArg(args[j], XtNheight, &pw_height); j++;
\r
5208 XtGetValues(shell, args, j);
\r
5209 commentH = pw_height + (lines - 1) * ew_height;
\r
5210 commentW = bw_width - 16;
\r
5212 XSync(xDisplay, False);
\r
5214 /* This code seems to tickle an X bug if it is executed too soon
\r
5215 after xboard starts up. The coordinates get transformed as if
\r
5216 the main window was positioned at (0, 0).
\r
5218 XtTranslateCoords(shellWidget,
\r
5219 (bw_width - commentW) / 2, 0 - commentH / 2,
\r
5220 &commentX, &commentY);
\r
5222 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
\r
5223 RootWindowOfScreen(XtScreen(shellWidget)),
\r
5224 (bw_width - commentW) / 2, 0 - commentH / 2,
\r
5228 #endif /*!NOTDEF*/
\r
5229 if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/
\r
5232 XtSetArg(args[j], XtNheight, commentH); j++;
\r
5233 XtSetArg(args[j], XtNwidth, commentW); j++;
\r
5234 XtSetArg(args[j], XtNx, commentX); j++;
\r
5235 XtSetArg(args[j], XtNy, commentY); j++;
\r
5236 XtSetValues(shell, args, j);
\r
5237 XtSetKeyboardFocus(shell, edit);
\r
5242 /* Used for analysis window and ICS input window */
\r
5243 Widget MiscCreate(name, text, mutable, callback, lines)
\r
5244 char *name, *text;
\r
5245 int /*Boolean*/ mutable;
\r
5246 XtCallbackProc callback;
\r
5250 Widget shell, layout, form, edit;
\r
5252 Dimension bw_width, pw_height, ew_height, w, h;
\r
5258 XtSetArg(args[j], XtNresizable, True); j++;
\r
5261 XtCreatePopupShell(name, topLevelShellWidgetClass,
\r
5262 shellWidget, args, j);
\r
5265 XtCreatePopupShell(name, transientShellWidgetClass,
\r
5266 shellWidget, args, j);
\r
5269 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
\r
5270 layoutArgs, XtNumber(layoutArgs));
\r
5272 XtCreateManagedWidget("form", formWidgetClass, layout,
\r
5273 formArgs, XtNumber(formArgs));
\r
5277 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
\r
5278 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
\r
5280 XtSetArg(args[j], XtNstring, text); j++;
\r
5281 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
5282 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5283 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5284 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
5285 XtSetArg(args[j], XtNresizable, True); j++;
\r
5287 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
\r
5289 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
\r
5290 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
\r
5292 XtSetArg(args[j], XtNautoFill, True); j++;
\r
5293 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
\r
5295 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
\r
5297 XtRealizeWidget(shell);
\r
5300 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5301 XtGetValues(boardWidget, args, j);
\r
5304 XtSetArg(args[j], XtNheight, &ew_height); j++;
\r
5305 XtGetValues(edit, args, j);
\r
5308 XtSetArg(args[j], XtNheight, &pw_height); j++;
\r
5309 XtGetValues(shell, args, j);
\r
5310 h = pw_height + (lines - 1) * ew_height;
\r
5311 w = bw_width - 16;
\r
5313 XSync(xDisplay, False);
\r
5315 /* This code seems to tickle an X bug if it is executed too soon
\r
5316 after xboard starts up. The coordinates get transformed as if
\r
5317 the main window was positioned at (0, 0).
\r
5319 XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);
\r
5321 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
\r
5322 RootWindowOfScreen(XtScreen(shellWidget)),
\r
5323 (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
\r
5324 #endif /*!NOTDEF*/
\r
5327 if (y < 0) y = 0; /*avoid positioning top offscreen*/
\r
5330 XtSetArg(args[j], XtNheight, h); j++;
\r
5331 XtSetArg(args[j], XtNwidth, w); j++;
\r
5332 XtSetArg(args[j], XtNx, x); j++;
\r
5333 XtSetArg(args[j], XtNy, y); j++;
\r
5334 XtSetValues(shell, args, j);
\r
5340 static int savedIndex; /* gross that this is global */
\r
5342 void EditCommentPopUp(index, title, text)
\r
5344 char *title, *text;
\r
5350 savedIndex = index;
\r
5351 if (text == NULL) text = "";
\r
5353 if (editShell == NULL) {
\r
5355 CommentCreate(title, text, True, EditCommentCallback, 4);
\r
5356 XtRealizeWidget(editShell);
\r
5357 CatchDeleteWindow(editShell, "EditCommentPopDown");
\r
5359 edit = XtNameToWidget(editShell, "*form.text");
\r
5361 XtSetArg(args[j], XtNstring, text); j++;
\r
5362 XtSetValues(edit, args, j);
\r
5364 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5365 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5366 XtSetValues(editShell, args, j);
\r
5369 XtPopup(editShell, XtGrabNone);
\r
5373 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
5374 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
\r
5378 void EditCommentCallback(w, client_data, call_data)
\r
5380 XtPointer client_data, call_data;
\r
5388 XtSetArg(args[j], XtNlabel, &name); j++;
\r
5389 XtGetValues(w, args, j);
\r
5391 if (strcmp(name, _("ok")) == 0) {
\r
5392 edit = XtNameToWidget(editShell, "*form.text");
\r
5394 XtSetArg(args[j], XtNstring, &val); j++;
\r
5395 XtGetValues(edit, args, j);
\r
5396 ReplaceComment(savedIndex, val);
\r
5397 EditCommentPopDown();
\r
5398 } else if (strcmp(name, _("cancel")) == 0) {
\r
5399 EditCommentPopDown();
\r
5400 } else if (strcmp(name, _("clear")) == 0) {
\r
5401 edit = XtNameToWidget(editShell, "*form.text");
\r
5402 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
\r
5403 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
\r
5407 void EditCommentPopDown()
\r
5412 if (!editUp) return;
\r
5414 XtSetArg(args[j], XtNx, &commentX); j++;
\r
5415 XtSetArg(args[j], XtNy, &commentY); j++;
\r
5416 XtSetArg(args[j], XtNheight, &commentH); j++;
\r
5417 XtSetArg(args[j], XtNwidth, &commentW); j++;
\r
5418 XtGetValues(editShell, args, j);
\r
5419 XtPopdown(editShell);
\r
5422 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
5423 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
\r
5427 void ICSInputBoxPopUp()
\r
5432 char *title = _("ICS Input");
\r
5433 XtTranslations tr;
\r
5435 if (ICSInputShell == NULL) {
\r
5436 ICSInputShell = MiscCreate(title, "", True, NULL, 1);
\r
5437 tr = XtParseTranslationTable(ICSInputTranslations);
\r
5438 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5439 XtOverrideTranslations(edit, tr);
\r
5440 XtRealizeWidget(ICSInputShell);
\r
5441 CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
\r
5444 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5446 XtSetArg(args[j], XtNstring, ""); j++;
\r
5447 XtSetValues(edit, args, j);
\r
5449 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5450 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5451 XtSetValues(ICSInputShell, args, j);
\r
5454 XtPopup(ICSInputShell, XtGrabNone);
\r
5455 XtSetKeyboardFocus(ICSInputShell, edit);
\r
5457 ICSInputBoxUp = True;
\r
5459 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
5460 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
\r
5464 void ICSInputSendText()
\r
5471 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5473 XtSetArg(args[j], XtNstring, &val); j++;
\r
5474 XtGetValues(edit, args, j);
\r
5475 SendMultiLineToICS(val);
\r
5476 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
\r
5477 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
\r
5480 void ICSInputBoxPopDown()
\r
5485 if (!ICSInputBoxUp) return;
\r
5487 XtPopdown(ICSInputShell);
\r
5488 ICSInputBoxUp = False;
\r
5490 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
5491 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
\r
5495 void CommentPopUp(title, text)
\r
5496 char *title, *text;
\r
5502 if (commentShell == NULL) {
\r
5504 CommentCreate(title, text, False, CommentCallback, 4);
\r
5505 XtRealizeWidget(commentShell);
\r
5506 CatchDeleteWindow(commentShell, "CommentPopDown");
\r
5508 edit = XtNameToWidget(commentShell, "*form.text");
\r
5510 XtSetArg(args[j], XtNstring, text); j++;
\r
5511 XtSetValues(edit, args, j);
\r
5513 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5514 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5515 XtSetValues(commentShell, args, j);
\r
5518 XtPopup(commentShell, XtGrabNone);
\r
5519 XSync(xDisplay, False);
\r
5524 void AnalysisPopUp(title, text)
\r
5525 char *title, *text;
\r
5531 if (analysisShell == NULL) {
\r
5532 analysisShell = MiscCreate(title, text, False, NULL, 4);
\r
5533 XtRealizeWidget(analysisShell);
\r
5534 CatchDeleteWindow(analysisShell, "AnalysisPopDown");
\r
5537 edit = XtNameToWidget(analysisShell, "*form.text");
\r
5539 XtSetArg(args[j], XtNstring, text); j++;
\r
5540 XtSetValues(edit, args, j);
\r
5542 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5543 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5544 XtSetValues(analysisShell, args, j);
\r
5547 if (!analysisUp) {
\r
5548 XtPopup(analysisShell, XtGrabNone);
\r
5550 XSync(xDisplay, False);
\r
5552 analysisUp = True;
\r
5555 void CommentCallback(w, client_data, call_data)
\r
5557 XtPointer client_data, call_data;
\r
5564 XtSetArg(args[j], XtNlabel, &name); j++;
\r
5565 XtGetValues(w, args, j);
\r
5567 if (strcmp(name, _("close")) == 0) {
\r
5569 } else if (strcmp(name, _("edit")) == 0) {
\r
5571 EditCommentEvent();
\r
5576 void CommentPopDown()
\r
5581 if (!commentUp) return;
\r
5583 XtSetArg(args[j], XtNx, &commentX); j++;
\r
5584 XtSetArg(args[j], XtNy, &commentY); j++;
\r
5585 XtSetArg(args[j], XtNwidth, &commentW); j++;
\r
5586 XtSetArg(args[j], XtNheight, &commentH); j++;
\r
5587 XtGetValues(commentShell, args, j);
\r
5588 XtPopdown(commentShell);
\r
5589 XSync(xDisplay, False);
\r
5590 commentUp = False;
\r
5593 void AnalysisPopDown()
\r
5595 if (!analysisUp) return;
\r
5596 XtPopdown(analysisShell);
\r
5597 XSync(xDisplay, False);
\r
5598 analysisUp = False;
\r
5599 if (appData.icsEngineAnalyze) ExitAnalyzeMode(); /* [DM] icsEngineAnalyze */
\r
5603 void FileNamePopUp(label, def, proc, openMode)
\r
5610 Widget popup, layout, dialog, edit;
\r
5611 Window root, child;
\r
5614 unsigned int mask;
\r
5616 fileProc = proc; /* I can't see a way not */
\r
5617 fileOpenMode = openMode; /* to use globals here */
\r
5620 XtSetArg(args[i], XtNresizable, True); i++;
\r
5621 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
\r
5622 XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++;
\r
5623 fileNameShell = popup =
\r
5624 XtCreatePopupShell("File name prompt", transientShellWidgetClass,
\r
5625 shellWidget, args, i);
\r
5628 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
\r
5629 layoutArgs, XtNumber(layoutArgs));
\r
5632 XtSetArg(args[i], XtNlabel, label); i++;
\r
5633 XtSetArg(args[i], XtNvalue, def); i++;
\r
5634 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
5635 dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
\r
5638 XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog);
\r
5639 XawDialogAddButton(dialog, _("cancel"), FileNameCallback,
\r
5640 (XtPointer) dialog);
\r
5642 XtRealizeWidget(popup);
\r
5643 CatchDeleteWindow(popup, "FileNamePopDown");
\r
5645 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
\r
5646 &x, &y, &win_x, &win_y, &mask);
\r
5648 XtSetArg(args[0], XtNx, x - 10);
\r
5649 XtSetArg(args[1], XtNy, y - 30);
\r
5650 XtSetValues(popup, args, 2);
\r
5652 XtPopup(popup, XtGrabExclusive);
\r
5653 filenameUp = True;
\r
5655 edit = XtNameToWidget(dialog, "*value");
\r
5656 XtSetKeyboardFocus(popup, edit);
\r
5659 void FileNamePopDown()
\r
5661 if (!filenameUp) return;
\r
5662 XtPopdown(fileNameShell);
\r
5663 XtDestroyWidget(fileNameShell);
\r
5664 filenameUp = False;
\r
5668 void FileNameCallback(w, client_data, call_data)
\r
5670 XtPointer client_data, call_data;
\r
5675 XtSetArg(args[0], XtNlabel, &name);
\r
5676 XtGetValues(w, args, 1);
\r
5678 if (strcmp(name, _("cancel")) == 0) {
\r
5679 FileNamePopDown();
\r
5683 FileNameAction(w, NULL, NULL, NULL);
\r
5686 void FileNameAction(w, event, prms, nprms)
\r
5692 char buf[MSG_SIZ];
\r
5695 char *p, *fullname;
\r
5698 name = XawDialogGetValueString(w = XtParent(w));
\r
5700 if ((name != NULL) && (*name != NULLCHAR)) {
\r
5701 strcpy(buf, name);
\r
5702 XtPopdown(w = XtParent(XtParent(w)));
\r
5703 XtDestroyWidget(w);
\r
5704 filenameUp = False;
\r
5706 p = strrchr(buf, ' ');
\r
5713 fullname = ExpandPathName(buf);
\r
5715 ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
\r
5718 f = fopen(fullname, fileOpenMode);
\r
5720 DisplayError(_("Failed to open file"), errno);
\r
5722 (void) (*fileProc)(f, index, buf);
\r
5729 XtPopdown(w = XtParent(XtParent(w)));
\r
5730 XtDestroyWidget(w);
\r
5731 filenameUp = False;
\r
5735 void PromotionPopUp()
\r
5738 Widget dialog, layout;
\r
5740 Dimension bw_width, pw_width;
\r
5744 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5745 XtGetValues(boardWidget, args, j);
\r
5748 XtSetArg(args[j], XtNresizable, True); j++;
\r
5749 XtSetArg(args[j], XtNtitle, XtNewString(_("Promotion"))); j++;
\r
5751 XtCreatePopupShell("Promotion", transientShellWidgetClass,
\r
5752 shellWidget, args, j);
\r
5754 XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
\r
5755 layoutArgs, XtNumber(layoutArgs));
\r
5758 XtSetArg(args[j], XtNlabel, _("Promote pawn to what?")); j++;
\r
5759 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
5760 dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
\r
5763 XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
\r
5764 (XtPointer) dialog);
\r
5765 XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
\r
5766 (XtPointer) dialog);
\r
5767 XawDialogAddButton(dialog, _("Bishop"), PromotionCallback,
\r
5768 (XtPointer) dialog);
\r
5769 XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
\r
5770 (XtPointer) dialog);
\r
5771 if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
\r
5772 gameInfo.variant == VariantGiveaway) {
\r
5773 XawDialogAddButton(dialog, _("King"), PromotionCallback,
\r
5774 (XtPointer) dialog);
\r
5776 XawDialogAddButton(dialog, _("cancel"), PromotionCallback,
\r
5777 (XtPointer) dialog);
\r
5779 XtRealizeWidget(promotionShell);
\r
5780 CatchDeleteWindow(promotionShell, "PromotionPopDown");
\r
5783 XtSetArg(args[j], XtNwidth, &pw_width); j++;
\r
5784 XtGetValues(promotionShell, args, j);
\r
5786 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
\r
5787 lineGap + squareSize/3 +
\r
5788 ((toY == BOARD_HEIGHT-1) ^ (flipView) ?
\r
5789 0 : 6*(squareSize + lineGap)), &x, &y);
\r
5792 XtSetArg(args[j], XtNx, x); j++;
\r
5793 XtSetArg(args[j], XtNy, y); j++;
\r
5794 XtSetValues(promotionShell, args, j);
\r
5796 XtPopup(promotionShell, XtGrabNone);
\r
5798 promotionUp = True;
\r
5801 void PromotionPopDown()
\r
5803 if (!promotionUp) return;
\r
5804 XtPopdown(promotionShell);
\r
5805 XtDestroyWidget(promotionShell);
\r
5806 promotionUp = False;
\r
5809 void PromotionCallback(w, client_data, call_data)
\r
5811 XtPointer client_data, call_data;
\r
5817 XtSetArg(args[0], XtNlabel, &name);
\r
5818 XtGetValues(w, args, 1);
\r
5820 PromotionPopDown();
\r
5822 if (fromX == -1) return;
\r
5824 if (strcmp(name, _("cancel")) == 0) {
\r
5825 fromX = fromY = -1;
\r
5826 ClearHighlights();
\r
5828 } else if (strcmp(name, _("Knight")) == 0) {
\r
5831 promoChar = ToLower(name[0]);
\r
5834 UserMoveEvent(fromX, fromY, toX, toY, promoChar);
\r
5836 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5837 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5838 fromX = fromY = -1;
\r
5842 void ErrorCallback(w, client_data, call_data)
\r
5844 XtPointer client_data, call_data;
\r
5847 XtPopdown(w = XtParent(XtParent(XtParent(w))));
\r
5848 XtDestroyWidget(w);
\r
5849 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
\r
5853 void ErrorPopDown()
\r
5855 if (!errorUp) return;
\r
5857 XtPopdown(errorShell);
\r
5858 XtDestroyWidget(errorShell);
\r
5859 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
\r
5862 void ErrorPopUp(title, label, modal)
\r
5863 char *title, *label;
\r
5867 Widget dialog, layout;
\r
5871 Dimension bw_width, pw_width;
\r
5872 Dimension pw_height;
\r
5876 XtSetArg(args[i], XtNresizable, True); i++;
\r
5877 XtSetArg(args[i], XtNtitle, title); i++;
\r
5879 XtCreatePopupShell("errorpopup", transientShellWidgetClass,
\r
5880 shellWidget, args, i);
\r
5882 XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,
\r
5883 layoutArgs, XtNumber(layoutArgs));
\r
5886 XtSetArg(args[i], XtNlabel, label); i++;
\r
5887 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
5888 dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
\r
5891 XawDialogAddButton(dialog, _("ok"), ErrorCallback, (XtPointer) dialog);
\r
5893 XtRealizeWidget(errorShell);
\r
5894 CatchDeleteWindow(errorShell, "ErrorPopDown");
\r
5897 XtSetArg(args[i], XtNwidth, &bw_width); i++;
\r
5898 XtGetValues(boardWidget, args, i);
\r
5900 XtSetArg(args[i], XtNwidth, &pw_width); i++;
\r
5901 XtSetArg(args[i], XtNheight, &pw_height); i++;
\r
5902 XtGetValues(errorShell, args, i);
\r
5905 /* This code seems to tickle an X bug if it is executed too soon
\r
5906 after xboard starts up. The coordinates get transformed as if
\r
5907 the main window was positioned at (0, 0).
\r
5909 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
\r
5910 0 - pw_height + squareSize / 3, &x, &y);
\r
5912 XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
\r
5913 RootWindowOfScreen(XtScreen(boardWidget)),
\r
5914 (bw_width - pw_width) / 2,
\r
5915 0 - pw_height + squareSize / 3, &xx, &yy, &junk);
\r
5919 if (y < 0) y = 0; /*avoid positioning top offscreen*/
\r
5922 XtSetArg(args[i], XtNx, x); i++;
\r
5923 XtSetArg(args[i], XtNy, y); i++;
\r
5924 XtSetValues(errorShell, args, i);
\r
5927 XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);
\r
5930 /* Disable all user input other than deleting the window */
\r
5931 static int frozen = 0;
\r
5934 if (frozen) return;
\r
5935 /* Grab by a widget that doesn't accept input */
\r
5936 XtAddGrab(messageWidget, TRUE, FALSE);
\r
5940 /* Undo a FreezeUI */
\r
5943 if (!frozen) return;
\r
5944 XtRemoveGrab(messageWidget);
\r
5948 char *ModeToWidgetName(mode)
\r
5952 case BeginningOfGame:
\r
5953 if (appData.icsActive)
\r
5954 return "menuMode.ICS Client";
\r
5955 else if (appData.noChessProgram ||
\r
5956 *appData.cmailGameName != NULLCHAR)
\r
5957 return "menuMode.Edit Game";
\r
5959 return "menuMode.Machine Black";
\r
5960 case MachinePlaysBlack:
\r
5961 return "menuMode.Machine Black";
\r
5962 case MachinePlaysWhite:
\r
5963 return "menuMode.Machine White";
\r
5965 return "menuMode.Analysis Mode";
\r
5967 return "menuMode.Analyze File";
\r
5968 case TwoMachinesPlay:
\r
5969 return "menuMode.Two Machines";
\r
5971 return "menuMode.Edit Game";
\r
5972 case PlayFromGameFile:
\r
5973 return "menuFile.Load Game";
\r
5974 case EditPosition:
\r
5975 return "menuMode.Edit Position";
\r
5977 return "menuMode.Training";
\r
5978 case IcsPlayingWhite:
\r
5979 case IcsPlayingBlack:
\r
5980 case IcsObserving:
\r
5982 case IcsExamining:
\r
5983 return "menuMode.ICS Client";
\r
5990 void ModeHighlight()
\r
5993 static int oldPausing = FALSE;
\r
5994 static GameMode oldmode = (GameMode) -1;
\r
5997 if (!boardWidget || !XtIsRealized(boardWidget)) return;
\r
5999 if (pausing != oldPausing) {
\r
6000 oldPausing = pausing;
\r
6002 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6004 XtSetArg(args[0], XtNleftBitmap, None);
\r
6006 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),
\r
6009 if (appData.showButtonBar) {
\r
6012 XtSetArg(args[0], XtNbackground, buttonForegroundPixel);
\r
6013 XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);
\r
6015 XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);
\r
6016 XtSetArg(args[1], XtNforeground, buttonForegroundPixel);
\r
6019 /* Always toggle, don't set. Previous code messes up when
\r
6020 invoked while the button is pressed, as releasing it
\r
6021 toggles the state again. */
\r
6023 Pixel oldbg, oldfg;
\r
6024 XtSetArg(args[0], XtNbackground, &oldbg);
\r
6025 XtSetArg(args[1], XtNforeground, &oldfg);
\r
6026 XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),
\r
6028 XtSetArg(args[0], XtNbackground, oldfg);
\r
6029 XtSetArg(args[1], XtNforeground, oldbg);
\r
6032 XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
\r
6036 wname = ModeToWidgetName(oldmode);
\r
6037 if (wname != NULL) {
\r
6038 XtSetArg(args[0], XtNleftBitmap, None);
\r
6039 XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
\r
6041 wname = ModeToWidgetName(gameMode);
\r
6042 if (wname != NULL) {
\r
6043 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6044 XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
\r
6046 oldmode = gameMode;
\r
6048 /* Maybe all the enables should be handled here, not just this one */
\r
6049 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),
\r
6050 gameMode == Training || gameMode == PlayFromGameFile);
\r
6055 * Button/menu procedures
\r
6057 void ResetProc(w, event, prms, nprms)
\r
6064 AnalysisPopDown();
\r
6067 int LoadGamePopUp(f, gameNumber, title)
\r
6072 cmailMsgLoaded = FALSE;
\r
6073 if (gameNumber == 0) {
\r
6074 int error = GameListBuild(f);
\r
6076 DisplayError(_("Cannot build game list"), error);
\r
6077 } else if (!ListEmpty(&gameList) &&
\r
6078 ((ListGame *) gameList.tailPred)->number > 1) {
\r
6079 GameListPopUp(f, title);
\r
6082 GameListDestroy();
\r
6085 return LoadGame(f, gameNumber, title, FALSE);
\r
6088 void LoadGameProc(w, event, prms, nprms)
\r
6094 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
\r
6095 Reset(FALSE, TRUE);
\r
6097 FileNamePopUp(_("Load game file name?"), "", LoadGamePopUp, "rb");
\r
6100 void LoadNextGameProc(w, event, prms, nprms)
\r
6109 void LoadPrevGameProc(w, event, prms, nprms)
\r
6118 void ReloadGameProc(w, event, prms, nprms)
\r
6127 void LoadNextPositionProc(w, event, prms, nprms)
\r
6133 ReloadPosition(1);
\r
6136 void LoadPrevPositionProc(w, event, prms, nprms)
\r
6142 ReloadPosition(-1);
\r
6145 void ReloadPositionProc(w, event, prms, nprms)
\r
6151 ReloadPosition(0);
\r
6154 void LoadPositionProc(w, event, prms, nprms)
\r
6160 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
\r
6161 Reset(FALSE, TRUE);
\r
6163 FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
\r
6166 void SaveGameProc(w, event, prms, nprms)
\r
6172 FileNamePopUp(_("Save game file name?"),
\r
6173 DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
\r
6177 void SavePositionProc(w, event, prms, nprms)
\r
6183 FileNamePopUp(_("Save position file name?"),
\r
6184 DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
\r
6185 SavePosition, "a");
\r
6188 void ReloadCmailMsgProc(w, event, prms, nprms)
\r
6194 ReloadCmailMsgEvent(FALSE);
\r
6197 void MailMoveProc(w, event, prms, nprms)
\r
6206 /* this variable is shared between CopyPositionProc and SendPositionSelection */
\r
6207 static char *selected_fen_position=NULL;
\r
6210 SendPositionSelection(Widget w, Atom *selection, Atom *target,
\r
6211 Atom *type_return, XtPointer *value_return,
\r
6212 unsigned long *length_return, int *format_return)
\r
6214 char *selection_tmp;
\r
6216 if (!selected_fen_position) return False; /* should never happen */
\r
6217 if (*target == XA_STRING){
\r
6218 /* note: since no XtSelectionDoneProc was registered, Xt will
\r
6219 * automatically call XtFree on the value returned. So have to
\r
6220 * make a copy of it allocated with XtMalloc */
\r
6221 selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
\r
6222 strcpy(selection_tmp, selected_fen_position);
\r
6224 *value_return=selection_tmp;
\r
6225 *length_return=strlen(selection_tmp);
\r
6226 *type_return=XA_STRING;
\r
6227 *format_return = 8; /* bits per byte */
\r
6234 /* note: when called from menu all parameters are NULL, so no clue what the
\r
6235 * Widget which was clicked on was, or what the click event was
\r
6237 void CopyPositionProc(w, event, prms, nprms)
\r
6245 if (selected_fen_position) free(selected_fen_position);
\r
6246 selected_fen_position = (char *)PositionToFEN(currentMove,1);
\r
6247 if (!selected_fen_position) return;
\r
6248 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
\r
6250 SendPositionSelection,
\r
6251 NULL/* lose_ownership_proc */ ,
\r
6252 NULL/* transfer_done_proc */);
\r
6254 free(selected_fen_position);
\r
6255 selected_fen_position=NULL;
\r
6259 /* function called when the data to Paste is ready */
\r
6261 PastePositionCB(Widget w, XtPointer client_data, Atom *selection,
\r
6262 Atom *type, XtPointer value, unsigned long *len, int *format)
\r
6264 char *fenstr=value;
\r
6265 if (value==NULL || *len==0) return; /* nothing had been selected to copy */
\r
6266 fenstr[*len]='\0'; /* normally this string is terminated, but be safe */
\r
6267 EditPositionPasteFEN(fenstr);
\r
6271 /* called when Paste Position button is pressed,
\r
6272 * all parameters will be NULL */
\r
6273 void PastePositionProc(w, event, prms, nprms)
\r
6279 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
\r
6280 /* (XtSelectionCallbackProc) */ PastePositionCB,
\r
6281 NULL, /* client_data passed to PastePositionCB */
\r
6283 /* better to use the time field from the event that triggered the
\r
6284 * call to this function, but that isn't trivial to get
\r
6292 SendGameSelection(Widget w, Atom *selection, Atom *target,
\r
6293 Atom *type_return, XtPointer *value_return,
\r
6294 unsigned long *length_return, int *format_return)
\r
6296 char *selection_tmp;
\r
6298 if (*target == XA_STRING){
\r
6299 FILE* f = fopen(gameCopyFilename, "r");
\r
6302 if (f == NULL) return False;
\r
6306 selection_tmp = XtMalloc(len + 1);
\r
6307 count = fread(selection_tmp, 1, len, f);
\r
6308 if (len != count) {
\r
6309 XtFree(selection_tmp);
\r
6312 selection_tmp[len] = NULLCHAR;
\r
6313 *value_return = selection_tmp;
\r
6314 *length_return = len;
\r
6315 *type_return = XA_STRING;
\r
6316 *format_return = 8; /* bits per byte */
\r
6323 /* note: when called from menu all parameters are NULL, so no clue what the
\r
6324 * Widget which was clicked on was, or what the click event was
\r
6326 void CopyGameProc(w, event, prms, nprms)
\r
6334 ret = SaveGameToFile(gameCopyFilename, FALSE);
\r
6337 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
\r
6339 SendGameSelection,
\r
6340 NULL/* lose_ownership_proc */ ,
\r
6341 NULL/* transfer_done_proc */);
\r
6344 /* function called when the data to Paste is ready */
\r
6346 PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
\r
6347 Atom *type, XtPointer value, unsigned long *len, int *format)
\r
6350 if (value == NULL || *len == 0) {
\r
6351 return; /* nothing had been selected to copy */
\r
6353 f = fopen(gamePasteFilename, "w");
\r
6355 DisplayError(_("Can't open temp file"), errno);
\r
6358 fwrite(value, 1, *len, f);
\r
6361 LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);
\r
6364 /* called when Paste Game button is pressed,
\r
6365 * all parameters will be NULL */
\r
6366 void PasteGameProc(w, event, prms, nprms)
\r
6372 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
\r
6373 /* (XtSelectionCallbackProc) */ PasteGameCB,
\r
6374 NULL, /* client_data passed to PasteGameCB */
\r
6376 /* better to use the time field from the event that triggered the
\r
6377 * call to this function, but that isn't trivial to get
\r
6385 void AutoSaveGame()
\r
6387 SaveGameProc(NULL, NULL, NULL, NULL);
\r
6391 void QuitProc(w, event, prms, nprms)
\r
6400 void PauseProc(w, event, prms, nprms)
\r
6410 void MachineBlackProc(w, event, prms, nprms)
\r
6416 MachineBlackEvent();
\r
6419 void MachineWhiteProc(w, event, prms, nprms)
\r
6425 MachineWhiteEvent();
\r
6428 void AnalyzeModeProc(w, event, prms, nprms)
\r
6434 char buf[MSG_SIZ];
\r
6436 if (!first.analysisSupport) {
\r
6437 sprintf(buf, _("%s does not support analysis"), first.tidy);
\r
6438 DisplayError(buf, 0);
\r
6441 /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */
\r
6442 if (appData.icsActive) {
\r
6443 if (gameMode != IcsObserving) {
\r
6444 sprintf(buf,_("You are not observing a game"));
\r
6445 DisplayError(buf, 0);
\r
6446 /* secure check */
\r
6447 if (appData.icsEngineAnalyze) {
\r
6448 if (appData.debugMode)
\r
6449 fprintf(debugFP, _("Found unexpected active ICS engine analyze \n"));
\r
6450 ExitAnalyzeMode();
\r
6455 /* if enable, use want disable icsEngineAnalyze */
\r
6456 if (appData.icsEngineAnalyze) {
\r
6457 ExitAnalyzeMode();
\r
6461 appData.icsEngineAnalyze = TRUE;
\r
6462 if (appData.debugMode)
\r
6463 fprintf(debugFP, _("ICS engine analyze starting... \n"));
\r
6465 if (!appData.showThinking)
\r
6466 ShowThinkingProc(w,event,prms,nprms);
\r
6468 AnalyzeModeEvent();
\r
6471 void AnalyzeFileProc(w, event, prms, nprms)
\r
6477 if (!first.analysisSupport) {
\r
6478 char buf[MSG_SIZ];
\r
6479 sprintf(buf, _("%s does not support analysis"), first.tidy);
\r
6480 DisplayError(buf, 0);
\r
6483 Reset(FALSE, TRUE);
\r
6485 if (!appData.showThinking)
\r
6486 ShowThinkingProc(w,event,prms,nprms);
\r
6488 AnalyzeFileEvent();
\r
6489 FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
\r
6490 AnalysisPeriodicEvent(1);
\r
6493 void TwoMachinesProc(w, event, prms, nprms)
\r
6499 TwoMachinesEvent();
\r
6502 void IcsClientProc(w, event, prms, nprms)
\r
6511 void EditGameProc(w, event, prms, nprms)
\r
6520 void EditPositionProc(w, event, prms, nprms)
\r
6526 EditPositionEvent();
\r
6529 void TrainingProc(w, event, prms, nprms)
\r
6538 void EditCommentProc(w, event, prms, nprms)
\r
6545 EditCommentPopDown();
\r
6547 EditCommentEvent();
\r
6551 void IcsInputBoxProc(w, event, prms, nprms)
\r
6557 if (ICSInputBoxUp) {
\r
6558 ICSInputBoxPopDown();
\r
6560 ICSInputBoxPopUp();
\r
6564 void AcceptProc(w, event, prms, nprms)
\r
6573 void DeclineProc(w, event, prms, nprms)
\r
6582 void RematchProc(w, event, prms, nprms)
\r
6591 void CallFlagProc(w, event, prms, nprms)
\r
6600 void DrawProc(w, event, prms, nprms)
\r
6609 void AbortProc(w, event, prms, nprms)
\r
6618 void AdjournProc(w, event, prms, nprms)
\r
6627 void ResignProc(w, event, prms, nprms)
\r
6636 void EnterKeyProc(w, event, prms, nprms)
\r
6642 if (ICSInputBoxUp == True)
\r
6643 ICSInputSendText();
\r
6646 void StopObservingProc(w, event, prms, nprms)
\r
6652 StopObservingEvent();
\r
6655 void StopExaminingProc(w, event, prms, nprms)
\r
6661 StopExaminingEvent();
\r
6665 void ForwardProc(w, event, prms, nprms)
\r
6675 void BackwardProc(w, event, prms, nprms)
\r
6684 void ToStartProc(w, event, prms, nprms)
\r
6693 void ToEndProc(w, event, prms, nprms)
\r
6702 void RevertProc(w, event, prms, nprms)
\r
6711 void TruncateGameProc(w, event, prms, nprms)
\r
6717 TruncateGameEvent();
\r
6719 void RetractMoveProc(w, event, prms, nprms)
\r
6725 RetractMoveEvent();
\r
6728 void MoveNowProc(w, event, prms, nprms)
\r
6738 void AlwaysQueenProc(w, event, prms, nprms)
\r
6746 appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
\r
6748 if (appData.alwaysPromoteToQueen) {
\r
6749 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6751 XtSetArg(args[0], XtNleftBitmap, None);
\r
6753 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
\r
6757 void AnimateDraggingProc(w, event, prms, nprms)
\r
6765 appData.animateDragging = !appData.animateDragging;
\r
6767 if (appData.animateDragging) {
\r
6768 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6771 XtSetArg(args[0], XtNleftBitmap, None);
\r
6773 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
\r
6777 void AnimateMovingProc(w, event, prms, nprms)
\r
6785 appData.animate = !appData.animate;
\r
6787 if (appData.animate) {
\r
6788 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6791 XtSetArg(args[0], XtNleftBitmap, None);
\r
6793 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
\r
6797 void AutocommProc(w, event, prms, nprms)
\r
6805 appData.autoComment = !appData.autoComment;
\r
6807 if (appData.autoComment) {
\r
6808 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6810 XtSetArg(args[0], XtNleftBitmap, None);
\r
6812 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
\r
6817 void AutoflagProc(w, event, prms, nprms)
\r
6825 appData.autoCallFlag = !appData.autoCallFlag;
\r
6827 if (appData.autoCallFlag) {
\r
6828 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6830 XtSetArg(args[0], XtNleftBitmap, None);
\r
6832 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
\r
6836 void AutoflipProc(w, event, prms, nprms)
\r
6844 appData.autoFlipView = !appData.autoFlipView;
\r
6846 if (appData.autoFlipView) {
\r
6847 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6849 XtSetArg(args[0], XtNleftBitmap, None);
\r
6851 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),
\r
6855 void AutobsProc(w, event, prms, nprms)
\r
6863 appData.autoObserve = !appData.autoObserve;
\r
6865 if (appData.autoObserve) {
\r
6866 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6868 XtSetArg(args[0], XtNleftBitmap, None);
\r
6870 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
\r
6874 void AutoraiseProc(w, event, prms, nprms)
\r
6882 appData.autoRaiseBoard = !appData.autoRaiseBoard;
\r
6884 if (appData.autoRaiseBoard) {
\r
6885 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6887 XtSetArg(args[0], XtNleftBitmap, None);
\r
6889 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),
\r
6893 void AutosaveProc(w, event, prms, nprms)
\r
6901 appData.autoSaveGames = !appData.autoSaveGames;
\r
6903 if (appData.autoSaveGames) {
\r
6904 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6906 XtSetArg(args[0], XtNleftBitmap, None);
\r
6908 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
6912 void BlindfoldProc(w, event, prms, nprms)
\r
6920 appData.blindfold = !appData.blindfold;
\r
6922 if (appData.blindfold) {
\r
6923 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6925 XtSetArg(args[0], XtNleftBitmap, None);
\r
6927 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),
\r
6930 DrawPosition(True, NULL);
\r
6933 void TestLegalityProc(w, event, prms, nprms)
\r
6941 appData.testLegality = !appData.testLegality;
\r
6943 if (appData.testLegality) {
\r
6944 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6946 XtSetArg(args[0], XtNleftBitmap, None);
\r
6948 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),
\r
6953 void FlashMovesProc(w, event, prms, nprms)
\r
6961 if (appData.flashCount == 0) {
\r
6962 appData.flashCount = 3;
\r
6964 appData.flashCount = -appData.flashCount;
\r
6967 if (appData.flashCount > 0) {
\r
6968 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6970 XtSetArg(args[0], XtNleftBitmap, None);
\r
6972 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),
\r
6976 void FlipViewProc(w, event, prms, nprms)
\r
6982 flipView = !flipView;
\r
6983 DrawPosition(True, NULL);
\r
6986 void GetMoveListProc(w, event, prms, nprms)
\r
6994 appData.getMoveList = !appData.getMoveList;
\r
6996 if (appData.getMoveList) {
\r
6997 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6998 GetMoveListEvent();
\r
7000 XtSetArg(args[0], XtNleftBitmap, None);
\r
7002 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
\r
7007 void HighlightDraggingProc(w, event, prms, nprms)
\r
7015 appData.highlightDragging = !appData.highlightDragging;
\r
7017 if (appData.highlightDragging) {
\r
7018 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7020 XtSetArg(args[0], XtNleftBitmap, None);
\r
7022 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7023 "menuOptions.Highlight Dragging"), args, 1);
\r
7027 void HighlightLastMoveProc(w, event, prms, nprms)
\r
7035 appData.highlightLastMove = !appData.highlightLastMove;
\r
7037 if (appData.highlightLastMove) {
\r
7038 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7040 XtSetArg(args[0], XtNleftBitmap, None);
\r
7042 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7043 "menuOptions.Highlight Last Move"), args, 1);
\r
7046 void IcsAlarmProc(w, event, prms, nprms)
\r
7054 appData.icsAlarm = !appData.icsAlarm;
\r
7056 if (appData.icsAlarm) {
\r
7057 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7059 XtSetArg(args[0], XtNleftBitmap, None);
\r
7061 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7062 "menuOptions.ICS Alarm"), args, 1);
\r
7065 void MoveSoundProc(w, event, prms, nprms)
\r
7073 appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
\r
7075 if (appData.ringBellAfterMoves) {
\r
7076 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7078 XtSetArg(args[0], XtNleftBitmap, None);
\r
7080 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
\r
7085 void OldSaveStyleProc(w, event, prms, nprms)
\r
7093 appData.oldSaveStyle = !appData.oldSaveStyle;
\r
7095 if (appData.oldSaveStyle) {
\r
7096 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7098 XtSetArg(args[0], XtNleftBitmap, None);
\r
7100 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
\r
7104 void PeriodicUpdatesProc(w, event, prms, nprms)
\r
7112 PeriodicUpdatesEvent(!appData.periodicUpdates);
\r
7114 if (appData.periodicUpdates) {
\r
7115 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7117 XtSetArg(args[0], XtNleftBitmap, None);
\r
7119 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),
\r
7123 void PonderNextMoveProc(w, event, prms, nprms)
\r
7131 PonderNextMoveEvent(!appData.ponderNextMove);
\r
7133 if (appData.ponderNextMove) {
\r
7134 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7136 XtSetArg(args[0], XtNleftBitmap, None);
\r
7138 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
\r
7142 void PopupExitMessageProc(w, event, prms, nprms)
\r
7150 appData.popupExitMessage = !appData.popupExitMessage;
\r
7152 if (appData.popupExitMessage) {
\r
7153 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7155 XtSetArg(args[0], XtNleftBitmap, None);
\r
7157 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7158 "menuOptions.Popup Exit Message"), args, 1);
\r
7161 void PopupMoveErrorsProc(w, event, prms, nprms)
\r
7169 appData.popupMoveErrors = !appData.popupMoveErrors;
\r
7171 if (appData.popupMoveErrors) {
\r
7172 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7174 XtSetArg(args[0], XtNleftBitmap, None);
\r
7176 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),
\r
7180 void PremoveProc(w, event, prms, nprms)
\r
7188 appData.premove = !appData.premove;
\r
7190 if (appData.premove) {
\r
7191 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7193 XtSetArg(args[0], XtNleftBitmap, None);
\r
7195 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7196 "menuOptions.Premove"), args, 1);
\r
7199 void QuietPlayProc(w, event, prms, nprms)
\r
7207 appData.quietPlay = !appData.quietPlay;
\r
7209 if (appData.quietPlay) {
\r
7210 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7212 XtSetArg(args[0], XtNleftBitmap, None);
\r
7214 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
\r
7218 void ShowCoordsProc(w, event, prms, nprms)
\r
7226 appData.showCoords = !appData.showCoords;
\r
7228 if (appData.showCoords) {
\r
7229 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7231 XtSetArg(args[0], XtNleftBitmap, None);
\r
7233 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
\r
7236 DrawPosition(True, NULL);
\r
7239 void ShowThinkingProc(w, event, prms, nprms)
\r
7247 appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
\r
7248 ShowThinkingEvent();
\r
7250 // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)
\r
7251 if (appData.showThinking) {
\r
7252 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7254 XtSetArg(args[0], XtNleftBitmap, None);
\r
7256 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
\r
7261 void HideThinkingProc(w, event, prms, nprms)
\r
7269 appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
\r
7270 ShowThinkingEvent();
\r
7272 if (appData.hideThinkingFromHuman) {
\r
7273 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7275 XtSetArg(args[0], XtNleftBitmap, None);
\r
7277 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
\r
7281 void InfoProc(w, event, prms, nprms)
\r
7287 char buf[MSG_SIZ];
\r
7288 sprintf(buf, "xterm -e info --directory %s --directory . -f %s &",
\r
7289 INFODIR, INFOFILE);
\r
7293 void ManProc(w, event, prms, nprms)
\r
7299 char buf[MSG_SIZ];
\r
7301 if (nprms && *nprms > 0)
\r
7305 sprintf(buf, "xterm -e man %s &", name);
\r
7309 void HintProc(w, event, prms, nprms)
\r
7318 void BookProc(w, event, prms, nprms)
\r
7327 void AboutProc(w, event, prms, nprms)
\r
7333 char buf[MSG_SIZ];
\r
7335 char *zippy = " (with Zippy code)";
\r
7339 sprintf(buf, "%s%s\n\n%s\n%s\n%s\n%s\n\n%s%s\n%s",
\r
7340 programVersion, zippy,
\r
7341 "Copyright 1991 Digital Equipment Corporation",
\r
7342 "Enhancements Copyright 1992-2001 Free Software Foundation",
\r
7343 "Enhancements Copyright 2005 Alessandro Scotti",
\r
7344 "Enhancements Copyright 2007-2008 H.G.Muller",
\r
7345 PRODUCT, " is free software and carries NO WARRANTY;",
\r
7346 "see the file COPYING for more information.");
\r
7347 ErrorPopUp(_("About XBoard"), buf, FALSE);
\r
7350 void DebugProc(w, event, prms, nprms)
\r
7356 appData.debugMode = !appData.debugMode;
\r
7359 void AboutGameProc(w, event, prms, nprms)
\r
7368 void NothingProc(w, event, prms, nprms)
\r
7377 void Iconify(w, event, prms, nprms)
\r
7385 fromX = fromY = -1;
\r
7386 XtSetArg(args[0], XtNiconic, True);
\r
7387 XtSetValues(shellWidget, args, 1);
\r
7390 void DisplayMessage(message, extMessage)
\r
7391 char *message, *extMessage;
\r
7393 char buf[MSG_SIZ];
\r
7398 sprintf(buf, "%s %s", message, extMessage);
\r
7401 message = extMessage;
\r
7404 XtSetArg(arg, XtNlabel, message);
\r
7405 XtSetValues(messageWidget, &arg, 1);
\r
7408 void DisplayTitle(text)
\r
7413 char title[MSG_SIZ];
\r
7414 char icon[MSG_SIZ];
\r
7416 if (text == NULL) text = "";
\r
7418 if (appData.titleInWindow) {
\r
7420 XtSetArg(args[i], XtNlabel, text); i++;
\r
7421 XtSetValues(titleWidget, args, i);
\r
7424 if (*text != NULLCHAR) {
\r
7425 strcpy(icon, text);
\r
7426 strcpy(title, text);
\r
7427 } else if (appData.icsActive) {
\r
7428 sprintf(icon, "%s", appData.icsHost);
\r
7429 sprintf(title, "%s: %s", programName, appData.icsHost);
\r
7430 } else if (appData.cmailGameName[0] != NULLCHAR) {
\r
7431 sprintf(icon, "%s", "CMail");
\r
7432 sprintf(title, "%s: %s", programName, "CMail");
\r
7434 // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
\r
7435 } else if (gameInfo.variant == VariantGothic) {
\r
7436 strcpy(icon, programName);
\r
7437 strcpy(title, GOTHIC);
\r
7440 } else if (gameInfo.variant == VariantFalcon) {
\r
7441 strcpy(icon, programName);
\r
7442 strcpy(title, FALCON);
\r
7444 } else if (appData.noChessProgram) {
\r
7445 strcpy(icon, programName);
\r
7446 strcpy(title, programName);
\r
7448 strcpy(icon, first.tidy);
\r
7449 sprintf(title, "%s: %s", programName, first.tidy);
\r
7452 XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++;
\r
7453 XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++;
\r
7454 XtSetValues(shellWidget, args, i);
\r
7458 void DisplayError(message, error)
\r
7462 char buf[MSG_SIZ];
\r
7465 if (appData.debugMode || appData.matchMode) {
\r
7466 fprintf(stderr, "%s: %s\n", programName, message);
\r
7469 if (appData.debugMode || appData.matchMode) {
\r
7470 fprintf(stderr, "%s: %s: %s\n",
\r
7471 programName, message, strerror(error));
\r
7473 sprintf(buf, "%s: %s", message, strerror(error));
\r
7476 ErrorPopUp(_("Error"), message, FALSE);
\r
7480 void DisplayMoveError(message)
\r
7483 fromX = fromY = -1;
\r
7484 ClearHighlights();
\r
7485 DrawPosition(FALSE, NULL);
\r
7486 if (appData.debugMode || appData.matchMode) {
\r
7487 fprintf(stderr, "%s: %s\n", programName, message);
\r
7489 if (appData.popupMoveErrors) {
\r
7490 ErrorPopUp(_("Error"), message, FALSE);
\r
7492 DisplayMessage(message, "");
\r
7497 void DisplayFatalError(message, error, status)
\r
7499 int error, status;
\r
7501 char buf[MSG_SIZ];
\r
7503 errorExitStatus = status;
\r
7505 fprintf(stderr, "%s: %s\n", programName, message);
\r
7507 fprintf(stderr, "%s: %s: %s\n",
\r
7508 programName, message, strerror(error));
\r
7509 sprintf(buf, "%s: %s", message, strerror(error));
\r
7512 if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
\r
7513 ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
\r
7515 ExitEvent(status);
\r
7519 void DisplayInformation(message)
\r
7523 ErrorPopUp(_("Information"), message, TRUE);
\r
7526 void DisplayNote(message)
\r
7530 ErrorPopUp(_("Note"), message, FALSE);
\r
7534 NullXErrorCheck(dpy, error_event)
\r
7536 XErrorEvent *error_event;
\r
7541 void DisplayIcsInteractionTitle(message)
\r
7544 if (oldICSInteractionTitle == NULL) {
\r
7545 /* Magic to find the old window title, adapted from vim */
\r
7546 char *wina = getenv("WINDOWID");
\r
7547 if (wina != NULL) {
\r
7548 Window win = (Window) atoi(wina);
\r
7549 Window root, parent, *children;
\r
7550 unsigned int nchildren;
\r
7551 int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);
\r
7553 if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
\r
7554 if (!XQueryTree(xDisplay, win, &root, &parent,
\r
7555 &children, &nchildren)) break;
\r
7556 if (children) XFree((void *)children);
\r
7557 if (parent == root || parent == 0) break;
\r
7560 XSetErrorHandler(oldHandler);
\r
7562 if (oldICSInteractionTitle == NULL) {
\r
7563 oldICSInteractionTitle = "xterm";
\r
7566 printf("\033]0;%s\007", message);
\r
7570 char pendingReplyPrefix[MSG_SIZ];
\r
7571 ProcRef pendingReplyPR;
\r
7573 void AskQuestionProc(w, event, prms, nprms)
\r
7579 if (*nprms != 4) {
\r
7580 fprintf(stderr, _("AskQuestionProc needed 4 parameters, got %d\n"),
\r
7584 AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);
\r
7587 void AskQuestionPopDown()
\r
7589 if (!askQuestionUp) return;
\r
7590 XtPopdown(askQuestionShell);
\r
7591 XtDestroyWidget(askQuestionShell);
\r
7592 askQuestionUp = False;
\r
7595 void AskQuestionReplyAction(w, event, prms, nprms)
\r
7601 char buf[MSG_SIZ];
\r
7605 reply = XawDialogGetValueString(w = XtParent(w));
\r
7606 strcpy(buf, pendingReplyPrefix);
\r
7607 if (*buf) strcat(buf, " ");
\r
7608 strcat(buf, reply);
\r
7609 strcat(buf, "\n");
\r
7610 OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
\r
7611 AskQuestionPopDown();
\r
7613 if (err) DisplayFatalError(_("Error writing to chess program"), err, 0);
\r
7616 void AskQuestionCallback(w, client_data, call_data)
\r
7618 XtPointer client_data, call_data;
\r
7623 XtSetArg(args[0], XtNlabel, &name);
\r
7624 XtGetValues(w, args, 1);
\r
7626 if (strcmp(name, _("cancel")) == 0) {
\r
7627 AskQuestionPopDown();
\r
7629 AskQuestionReplyAction(w, NULL, NULL, NULL);
\r
7633 void AskQuestion(title, question, replyPrefix, pr)
\r
7634 char *title, *question, *replyPrefix;
\r
7638 Widget popup, layout, dialog, edit;
\r
7639 Window root, child;
\r
7642 unsigned int mask;
\r
7644 strcpy(pendingReplyPrefix, replyPrefix);
\r
7645 pendingReplyPR = pr;
\r
7648 XtSetArg(args[i], XtNresizable, True); i++;
\r
7649 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
\r
7650 askQuestionShell = popup =
\r
7651 XtCreatePopupShell(title, transientShellWidgetClass,
\r
7652 shellWidget, args, i);
\r
7655 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
\r
7656 layoutArgs, XtNumber(layoutArgs));
\r
7659 XtSetArg(args[i], XtNlabel, question); i++;
\r
7660 XtSetArg(args[i], XtNvalue, ""); i++;
\r
7661 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
7662 dialog = XtCreateManagedWidget("question", dialogWidgetClass,
\r
7665 XawDialogAddButton(dialog, _("enter"), AskQuestionCallback,
\r
7666 (XtPointer) dialog);
\r
7667 XawDialogAddButton(dialog, _("cancel"), AskQuestionCallback,
\r
7668 (XtPointer) dialog);
\r
7670 XtRealizeWidget(popup);
\r
7671 CatchDeleteWindow(popup, "AskQuestionPopDown");
\r
7673 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
\r
7674 &x, &y, &win_x, &win_y, &mask);
\r
7676 XtSetArg(args[0], XtNx, x - 10);
\r
7677 XtSetArg(args[1], XtNy, y - 30);
\r
7678 XtSetValues(popup, args, 2);
\r
7680 XtPopup(popup, XtGrabExclusive);
\r
7681 askQuestionUp = True;
\r
7683 edit = XtNameToWidget(dialog, "*value");
\r
7684 XtSetKeyboardFocus(popup, edit);
\r
7692 if (*name == NULLCHAR) {
\r
7694 } else if (strcmp(name, "$") == 0) {
\r
7695 putc(BELLCHAR, stderr);
\r
7698 sprintf(buf, "%s '%s' &", appData.soundProgram, name);
\r
7706 PlaySound(appData.soundMove);
\r
7712 PlaySound(appData.soundIcsWin);
\r
7716 PlayIcsLossSound()
\r
7718 PlaySound(appData.soundIcsLoss);
\r
7722 PlayIcsDrawSound()
\r
7724 PlaySound(appData.soundIcsDraw);
\r
7728 PlayIcsUnfinishedSound()
\r
7730 PlaySound(appData.soundIcsUnfinished);
\r
7736 PlaySound(appData.soundIcsAlarm);
\r
7742 system("stty echo");
\r
7748 system("stty -echo");
\r
7752 Colorize(cc, continuation)
\r
7756 char buf[MSG_SIZ];
\r
7757 int count, outCount, error;
\r
7759 if (textColors[(int)cc].bg > 0) {
\r
7760 if (textColors[(int)cc].fg > 0) {
\r
7761 sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
\r
7762 textColors[(int)cc].fg, textColors[(int)cc].bg);
\r
7764 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
\r
7765 textColors[(int)cc].bg);
\r
7768 if (textColors[(int)cc].fg > 0) {
\r
7769 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
\r
7770 textColors[(int)cc].fg);
\r
7772 sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);
\r
7775 count = strlen(buf);
\r
7776 outCount = OutputToProcess(NoProc, buf, count, &error);
\r
7777 if (outCount < count) {
\r
7778 DisplayFatalError(_("Error writing to display"), error, 1);
\r
7781 if (continuation) return;
\r
7784 PlaySound(appData.soundShout);
\r
7787 PlaySound(appData.soundSShout);
\r
7789 case ColorChannel1:
\r
7790 PlaySound(appData.soundChannel1);
\r
7792 case ColorChannel:
\r
7793 PlaySound(appData.soundChannel);
\r
7796 PlaySound(appData.soundKibitz);
\r
7799 PlaySound(appData.soundTell);
\r
7801 case ColorChallenge:
\r
7802 PlaySound(appData.soundChallenge);
\r
7804 case ColorRequest:
\r
7805 PlaySound(appData.soundRequest);
\r
7808 PlaySound(appData.soundSeek);
\r
7819 return getpwuid(getuid())->pw_name;
\r
7822 static char *ExpandPathName(path)
\r
7825 static char static_buf[2000];
\r
7826 char *d, *s, buf[2000];
\r
7827 struct passwd *pwd;
\r
7832 while (*s && isspace(*s))
\r
7837 return static_buf;
\r
7841 if (*(s+1) == '/') {
\r
7842 strcpy(d, getpwuid(getuid())->pw_dir);
\r
7847 *strchr(buf, '/') = 0;
\r
7848 pwd = getpwnam(buf);
\r
7851 fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
\r
7855 strcpy(d, pwd->pw_dir);
\r
7856 strcat(d, strchr(s+1, '/'));
\r
7862 return static_buf;
\r
7867 static char host_name[MSG_SIZ];
\r
7869 #if HAVE_GETHOSTNAME
\r
7870 gethostname(host_name, MSG_SIZ);
\r
7872 #else /* not HAVE_GETHOSTNAME */
\r
7873 # if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
\r
7874 sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
\r
7876 # else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
\r
7877 return "localhost";
\r
7878 # endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
\r
7879 #endif /* not HAVE_GETHOSTNAME */
\r
7882 XtIntervalId delayedEventTimerXID = 0;
\r
7883 DelayedEventCallback delayedEventCallback = 0;
\r
7886 FireDelayedEvent()
\r
7888 delayedEventTimerXID = 0;
\r
7889 delayedEventCallback();
\r
7893 ScheduleDelayedEvent(cb, millisec)
\r
7894 DelayedEventCallback cb; long millisec;
\r
7896 delayedEventCallback = cb;
\r
7897 delayedEventTimerXID =
\r
7898 XtAppAddTimeOut(appContext, millisec,
\r
7899 (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
\r
7902 DelayedEventCallback
\r
7905 if (delayedEventTimerXID) {
\r
7906 return delayedEventCallback;
\r
7913 CancelDelayedEvent()
\r
7915 if (delayedEventTimerXID) {
\r
7916 XtRemoveTimeOut(delayedEventTimerXID);
\r
7917 delayedEventTimerXID = 0;
\r
7921 XtIntervalId loadGameTimerXID = 0;
\r
7923 int LoadGameTimerRunning()
\r
7925 return loadGameTimerXID != 0;
\r
7928 int StopLoadGameTimer()
\r
7930 if (loadGameTimerXID != 0) {
\r
7931 XtRemoveTimeOut(loadGameTimerXID);
\r
7932 loadGameTimerXID = 0;
\r
7940 LoadGameTimerCallback(arg, id)
\r
7944 loadGameTimerXID = 0;
\r
7945 AutoPlayGameLoop();
\r
7949 StartLoadGameTimer(millisec)
\r
7952 loadGameTimerXID =
\r
7953 XtAppAddTimeOut(appContext, millisec,
\r
7954 (XtTimerCallbackProc) LoadGameTimerCallback,
\r
7958 XtIntervalId analysisClockXID = 0;
\r
7961 AnalysisClockCallback(arg, id)
\r
7965 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
\r
7966 || appData.icsEngineAnalyze) { // [DM]
\r
7967 AnalysisPeriodicEvent(0);
\r
7968 StartAnalysisClock();
\r
7973 StartAnalysisClock()
\r
7975 analysisClockXID =
\r
7976 XtAppAddTimeOut(appContext, 2000,
\r
7977 (XtTimerCallbackProc) AnalysisClockCallback,
\r
7981 XtIntervalId clockTimerXID = 0;
\r
7983 int ClockTimerRunning()
\r
7985 return clockTimerXID != 0;
\r
7988 int StopClockTimer()
\r
7990 if (clockTimerXID != 0) {
\r
7991 XtRemoveTimeOut(clockTimerXID);
\r
7992 clockTimerXID = 0;
\r
8000 ClockTimerCallback(arg, id)
\r
8004 clockTimerXID = 0;
\r
8005 DecrementClocks();
\r
8009 StartClockTimer(millisec)
\r
8013 XtAppAddTimeOut(appContext, millisec,
\r
8014 (XtTimerCallbackProc) ClockTimerCallback,
\r
8019 DisplayTimerLabel(w, color, timer, highlight)
\r
8025 char buf[MSG_SIZ];
\r
8028 if (appData.clockMode) {
\r
8029 sprintf(buf, "%s: %s", color, TimeString(timer));
\r
8030 XtSetArg(args[0], XtNlabel, buf);
\r
8032 sprintf(buf, "%s ", color);
\r
8033 XtSetArg(args[0], XtNlabel, buf);
\r
8037 XtSetArg(args[1], XtNbackground, timerForegroundPixel);
\r
8038 XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
\r
8040 XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
\r
8041 XtSetArg(args[2], XtNforeground, timerForegroundPixel);
\r
8044 XtSetValues(w, args, 3);
\r
8048 DisplayWhiteClock(timeRemaining, highlight)
\r
8049 long timeRemaining;
\r
8054 if(appData.noGUI) return;
\r
8055 DisplayTimerLabel(whiteTimerWidget, _("White"), timeRemaining, highlight);
\r
8056 if (highlight && iconPixmap == bIconPixmap) {
\r
8057 iconPixmap = wIconPixmap;
\r
8058 XtSetArg(args[0], XtNiconPixmap, iconPixmap);
\r
8059 XtSetValues(shellWidget, args, 1);
\r
8064 DisplayBlackClock(timeRemaining, highlight)
\r
8065 long timeRemaining;
\r
8070 if(appData.noGUI) return;
\r
8071 DisplayTimerLabel(blackTimerWidget, _("Black"), timeRemaining, highlight);
\r
8072 if (highlight && iconPixmap == wIconPixmap) {
\r
8073 iconPixmap = bIconPixmap;
\r
8074 XtSetArg(args[0], XtNiconPixmap, iconPixmap);
\r
8075 XtSetValues(shellWidget, args, 1);
\r
8084 typedef int CPKind;
\r
8089 int fdTo, fdFrom;
\r
8093 int StartChildProcess(cmdLine, dir, pr)
\r
8098 char *argv[64], *p;
\r
8100 int to_prog[2], from_prog[2];
\r
8102 char buf[MSG_SIZ];
\r
8104 if (appData.debugMode) {
\r
8105 fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
\r
8108 /* We do NOT feed the cmdLine to the shell; we just
\r
8109 parse it into blank-separated arguments in the
\r
8110 most simple-minded way possible.
\r
8113 strcpy(buf, cmdLine);
\r
8117 p = strchr(p, ' ');
\r
8118 if (p == NULL) break;
\r
8123 SetUpChildIO(to_prog, from_prog);
\r
8125 if ((pid = fork()) == 0) {
\r
8126 /* Child process */
\r
8127 // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1
\r
8128 close(to_prog[1]); // first close the unused pipe ends
\r
8129 close(from_prog[0]);
\r
8130 dup2(to_prog[0], 0); // to_prog was created first, nd is the only one to use 0 or 1
\r
8131 dup2(from_prog[1], 1);
\r
8132 if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original
\r
8133 close(from_prog[1]); // and closing again loses one of the pipes!
\r
8134 if(fileno(stderr) >= 2) // better safe than sorry...
\r
8135 dup2(1, fileno(stderr)); /* force stderr to the pipe */
\r
8137 if (dir[0] != NULLCHAR && chdir(dir) != 0) {
\r
8142 nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc
\r
8144 execvp(argv[0], argv);
\r
8146 /* If we get here, exec failed */
\r
8151 /* Parent process */
\r
8152 close(to_prog[0]);
\r
8153 close(from_prog[1]);
\r
8155 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8156 cp->kind = CPReal;
\r
8158 cp->fdFrom = from_prog[0];
\r
8159 cp->fdTo = to_prog[1];
\r
8160 *pr = (ProcRef) cp;
\r
8164 // [HGM] kill: implement the 'hard killing' of AS's Winboard_x
\r
8165 static RETSIGTYPE AlarmCallBack(int n)
\r
8171 DestroyChildProcess(pr, signalType)
\r
8175 ChildProc *cp = (ChildProc *) pr;
\r
8177 if (cp->kind != CPReal) return;
\r
8178 cp->kind = CPNone;
\r
8179 if (signalType == 10) { // [HGM] kill: if it does not terminate in 3 sec, kill
\r
8180 signal(SIGALRM, AlarmCallBack);
\r
8182 if(wait((int *) 0) == -1) { // process does not terminate on its own accord
\r
8183 kill(cp->pid, SIGKILL); // kill it forcefully
\r
8184 wait((int *) 0); // and wait again
\r
8188 kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: use hard kill if so requested
\r
8190 /* Process is exiting either because of the kill or because of
\r
8191 a quit command sent by the backend; either way, wait for it to die.
\r
8195 close(cp->fdFrom);
\r
8200 InterruptChildProcess(pr)
\r
8203 ChildProc *cp = (ChildProc *) pr;
\r
8205 if (cp->kind != CPReal) return;
\r
8206 (void) kill(cp->pid, SIGINT); /* stop it thinking */
\r
8209 int OpenTelnet(host, port, pr)
\r
8214 char cmdLine[MSG_SIZ];
\r
8216 if (port[0] == NULLCHAR) {
\r
8217 sprintf(cmdLine, "%s %s", appData.telnetProgram, host);
\r
8219 sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);
\r
8221 return StartChildProcess(cmdLine, "", pr);
\r
8224 int OpenTCP(host, port, pr)
\r
8230 DisplayFatalError(_("Socket support is not configured in"), 0, 2);
\r
8231 #else /* !OMIT_SOCKETS */
\r
8233 struct sockaddr_in sa;
\r
8234 struct hostent *hp;
\r
8235 unsigned short uport;
\r
8238 if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
\r
8242 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
\r
8243 sa.sin_family = AF_INET;
\r
8244 sa.sin_addr.s_addr = INADDR_ANY;
\r
8245 uport = (unsigned short) 0;
\r
8246 sa.sin_port = htons(uport);
\r
8247 if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
\r
8251 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
\r
8252 if (!(hp = gethostbyname(host))) {
\r
8253 int b0, b1, b2, b3;
\r
8254 if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
\r
8255 hp = (struct hostent *) calloc(1, sizeof(struct hostent));
\r
8256 hp->h_addrtype = AF_INET;
\r
8258 hp->h_addr_list = (char **) calloc(2, sizeof(char *));
\r
8259 hp->h_addr_list[0] = (char *) malloc(4);
\r
8260 hp->h_addr_list[0][0] = b0;
\r
8261 hp->h_addr_list[0][1] = b1;
\r
8262 hp->h_addr_list[0][2] = b2;
\r
8263 hp->h_addr_list[0][3] = b3;
\r
8268 sa.sin_family = hp->h_addrtype;
\r
8269 uport = (unsigned short) atoi(port);
\r
8270 sa.sin_port = htons(uport);
\r
8271 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
\r
8273 if (connect(s, (struct sockaddr *) &sa,
\r
8274 sizeof(struct sockaddr_in)) < 0) {
\r
8278 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8279 cp->kind = CPSock;
\r
8283 *pr = (ProcRef) cp;
\r
8285 #endif /* !OMIT_SOCKETS */
\r
8290 int OpenCommPort(name, pr)
\r
8297 fd = open(name, 2, 0);
\r
8298 if (fd < 0) return errno;
\r
8300 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8301 cp->kind = CPComm;
\r
8305 *pr = (ProcRef) cp;
\r
8310 int OpenLoopback(pr)
\r
8314 int to[2], from[2];
\r
8316 SetUpChildIO(to, from);
\r
8318 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8319 cp->kind = CPLoop;
\r
8321 cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */
\r
8323 *pr = (ProcRef) cp;
\r
8328 int OpenRcmd(host, user, cmd, pr)
\r
8329 char *host, *user, *cmd;
\r
8332 DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
\r
8336 #define INPUT_SOURCE_BUF_SIZE 8192
\r
8343 InputCallback func;
\r
8345 char buf[INPUT_SOURCE_BUF_SIZE];
\r
8350 DoInputCallback(closure, source, xid)
\r
8355 InputSource *is = (InputSource *) closure;
\r
8360 if (is->lineByLine) {
\r
8361 count = read(is->fd, is->unused,
\r
8362 INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
\r
8364 (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
\r
8367 is->unused += count;
\r
8369 while (p < is->unused) {
\r
8370 q = memchr(p, '\n', is->unused - p);
\r
8371 if (q == NULL) break;
\r
8373 (is->func)(is, is->closure, p, q - p, 0);
\r
8377 while (p < is->unused) {
\r
8382 count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
\r
8387 (is->func)(is, is->closure, is->buf, count, error);
\r
8391 InputSourceRef AddInputSource(pr, lineByLine, func, closure)
\r
8394 InputCallback func;
\r
8398 ChildProc *cp = (ChildProc *) pr;
\r
8400 is = (InputSource *) calloc(1, sizeof(InputSource));
\r
8401 is->lineByLine = lineByLine;
\r
8403 if (pr == NoProc) {
\r
8404 is->kind = CPReal;
\r
8405 is->fd = fileno(stdin);
\r
8407 is->kind = cp->kind;
\r
8408 is->fd = cp->fdFrom;
\r
8411 is->unused = is->buf;
\r
8414 is->xid = XtAppAddInput(appContext, is->fd,
\r
8415 (XtPointer) (XtInputReadMask),
\r
8416 (XtInputCallbackProc) DoInputCallback,
\r
8418 is->closure = closure;
\r
8419 return (InputSourceRef) is;
\r
8423 RemoveInputSource(isr)
\r
8424 InputSourceRef isr;
\r
8426 InputSource *is = (InputSource *) isr;
\r
8428 if (is->xid == 0) return;
\r
8429 XtRemoveInput(is->xid);
\r
8433 int OutputToProcess(pr, message, count, outError)
\r
8439 ChildProc *cp = (ChildProc *) pr;
\r
8443 outCount = fwrite(message, 1, count, stdout);
\r
8445 outCount = write(cp->fdTo, message, count);
\r
8447 if (outCount == -1)
\r
8448 *outError = errno;
\r
8455 /* Output message to process, with "ms" milliseconds of delay
\r
8456 between each character. This is needed when sending the logon
\r
8457 script to ICC, which for some reason doesn't like the
\r
8458 instantaneous send. */
\r
8459 int OutputToProcessDelayed(pr, message, count, outError, msdelay)
\r
8466 ChildProc *cp = (ChildProc *) pr;
\r
8471 r = write(cp->fdTo, message++, 1);
\r
8473 *outError = errno;
\r
8478 TimeDelay(msdelay);
\r
8484 /**** Animation code by Hugh Fisher, DCS, ANU.
\r
8486 Known problem: if a window overlapping the board is
\r
8487 moved away while a piece is being animated underneath,
\r
8488 the newly exposed area won't be updated properly.
\r
8489 I can live with this.
\r
8491 Known problem: if you look carefully at the animation
\r
8492 of pieces in mono mode, they are being drawn as solid
\r
8493 shapes without interior detail while moving. Fixing
\r
8494 this would be a major complication for minimal return.
\r
8497 /* Masks for XPM pieces. Black and white pieces can have
\r
8498 different shapes, but in the interest of retaining my
\r
8499 sanity pieces must have the same outline on both light
\r
8500 and dark squares, and all pieces must use the same
\r
8501 background square colors/images. */
\r
8504 CreateAnimMasks (pieceDepth)
\r
8507 ChessSquare piece;
\r
8511 unsigned long plane;
\r
8514 /* Need a bitmap just to get a GC with right depth */
\r
8515 buf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8517 values.foreground = 1;
\r
8518 values.background = 0;
\r
8519 /* Don't use XtGetGC, not read only */
\r
8520 maskGC = XCreateGC(xDisplay, buf,
\r
8521 GCForeground | GCBackground, &values);
\r
8522 XFreePixmap(xDisplay, buf);
\r
8524 buf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8525 squareSize, squareSize, pieceDepth);
\r
8526 values.foreground = XBlackPixel(xDisplay, xScreen);
\r
8527 values.background = XWhitePixel(xDisplay, xScreen);
\r
8528 bufGC = XCreateGC(xDisplay, buf,
\r
8529 GCForeground | GCBackground, &values);
\r
8531 for (piece = WhitePawn; piece <= BlackKing; piece++) {
\r
8532 /* Begin with empty mask */
\r
8533 xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
\r
8534 squareSize, squareSize, 1);
\r
8535 XSetFunction(xDisplay, maskGC, GXclear);
\r
8536 XFillRectangle(xDisplay, xpmMask[piece], maskGC,
\r
8537 0, 0, squareSize, squareSize);
\r
8539 /* Take a copy of the piece */
\r
8544 XSetFunction(xDisplay, bufGC, GXcopy);
\r
8545 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
\r
8547 0, 0, squareSize, squareSize, 0, 0);
\r
8549 /* XOR the background (light) over the piece */
\r
8550 XSetFunction(xDisplay, bufGC, GXxor);
\r
8552 XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
\r
8553 0, 0, squareSize, squareSize, 0, 0);
\r
8555 XSetForeground(xDisplay, bufGC, lightSquareColor);
\r
8556 XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
\r
8559 /* We now have an inverted piece image with the background
\r
8560 erased. Construct mask by just selecting all the non-zero
\r
8561 pixels - no need to reconstruct the original image. */
\r
8562 XSetFunction(xDisplay, maskGC, GXor);
\r
8564 /* Might be quicker to download an XImage and create bitmap
\r
8565 data from it rather than this N copies per piece, but it
\r
8566 only takes a fraction of a second and there is a much
\r
8567 longer delay for loading the pieces. */
\r
8568 for (n = 0; n < pieceDepth; n ++) {
\r
8569 XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
\r
8570 0, 0, squareSize, squareSize,
\r
8572 plane = plane << 1;
\r
8576 XFreePixmap(xDisplay, buf);
\r
8577 XFreeGC(xDisplay, bufGC);
\r
8578 XFreeGC(xDisplay, maskGC);
\r
8582 InitAnimState (anim, info)
\r
8584 XWindowAttributes * info;
\r
8589 /* Each buffer is square size, same depth as window */
\r
8590 anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8591 squareSize, squareSize, info->depth);
\r
8592 anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8593 squareSize, squareSize, info->depth);
\r
8595 /* Create a plain GC for blitting */
\r
8596 mask = GCForeground | GCBackground | GCFunction |
\r
8597 GCPlaneMask | GCGraphicsExposures;
\r
8598 values.foreground = XBlackPixel(xDisplay, xScreen);
\r
8599 values.background = XWhitePixel(xDisplay, xScreen);
\r
8600 values.function = GXcopy;
\r
8601 values.plane_mask = AllPlanes;
\r
8602 values.graphics_exposures = False;
\r
8603 anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
\r
8605 /* Piece will be copied from an existing context at
\r
8606 the start of each new animation/drag. */
\r
8607 anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
\r
8609 /* Outline will be a read-only copy of an existing */
\r
8610 anim->outlineGC = None;
\r
8616 static int done = 0;
\r
8617 XWindowAttributes info;
\r
8621 XGetWindowAttributes(xDisplay, xBoardWindow, &info);
\r
8623 InitAnimState(&game, &info);
\r
8624 InitAnimState(&player, &info);
\r
8626 /* For XPM pieces, we need bitmaps to use as masks. */
\r
8628 CreateAnimMasks(info.depth);
\r
8631 #ifndef HAVE_USLEEP
\r
8633 static Boolean frameWaiting;
\r
8635 static RETSIGTYPE FrameAlarm (sig)
\r
8638 frameWaiting = False;
\r
8639 /* In case System-V style signals. Needed?? */
\r
8640 signal(SIGALRM, FrameAlarm);
\r
8647 struct itimerval delay;
\r
8649 XSync(xDisplay, False);
\r
8652 frameWaiting = True;
\r
8653 signal(SIGALRM, FrameAlarm);
\r
8654 delay.it_interval.tv_sec =
\r
8655 delay.it_value.tv_sec = time / 1000;
\r
8656 delay.it_interval.tv_usec =
\r
8657 delay.it_value.tv_usec = (time % 1000) * 1000;
\r
8658 setitimer(ITIMER_REAL, &delay, NULL);
\r
8660 /* Ugh -- busy-wait! --tpm */
\r
8661 while (frameWaiting);
\r
8663 while (frameWaiting) pause();
\r
8665 delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
\r
8666 delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
\r
8667 setitimer(ITIMER_REAL, &delay, NULL);
\r
8677 XSync(xDisplay, False);
\r
8679 usleep(time * 1000);
\r
8684 /* Convert board position to corner of screen rect and color */
\r
8687 ScreenSquare(column, row, pt, color)
\r
8688 int column; int row; XPoint * pt; int * color;
\r
8691 pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);
\r
8692 pt->y = lineGap + row * (squareSize + lineGap);
\r
8694 pt->x = lineGap + column * (squareSize + lineGap);
\r
8695 pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);
\r
8697 *color = SquareColor(row, column);
\r
8700 /* Convert window coords to square */
\r
8703 BoardSquare(x, y, column, row)
\r
8704 int x; int y; int * column; int * row;
\r
8706 *column = EventToSquare(x, BOARD_WIDTH);
\r
8707 if (flipView && *column >= 0)
\r
8708 *column = BOARD_WIDTH - 1 - *column;
\r
8709 *row = EventToSquare(y, BOARD_HEIGHT);
\r
8710 if (!flipView && *row >= 0)
\r
8711 *row = BOARD_HEIGHT - 1 - *row;
\r
8716 #undef Max /* just in case */
\r
8718 #define Max(a, b) ((a) > (b) ? (a) : (b))
\r
8719 #define Min(a, b) ((a) < (b) ? (a) : (b))
\r
8722 SetRect(rect, x, y, width, height)
\r
8723 XRectangle * rect; int x; int y; int width; int height;
\r
8727 rect->width = width;
\r
8728 rect->height = height;
\r
8731 /* Test if two frames overlap. If they do, return
\r
8732 intersection rect within old and location of
\r
8733 that rect within new. */
\r
8736 Intersect(old, new, size, area, pt)
\r
8737 XPoint * old; XPoint * new;
\r
8738 int size; XRectangle * area; XPoint * pt;
\r
8740 if (old->x > new->x + size || new->x > old->x + size ||
\r
8741 old->y > new->y + size || new->y > old->y + size) {
\r
8744 SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0),
\r
8745 size - abs(old->x - new->x), size - abs(old->y - new->y));
\r
8746 pt->x = Max(old->x - new->x, 0);
\r
8747 pt->y = Max(old->y - new->y, 0);
\r
8752 /* For two overlapping frames, return the rect(s)
\r
8753 in the old that do not intersect with the new. */
\r
8756 CalcUpdateRects(old, new, size, update, nUpdates)
\r
8757 XPoint * old; XPoint * new; int size;
\r
8758 XRectangle update[]; int * nUpdates;
\r
8762 /* If old = new (shouldn't happen) then nothing to draw */
\r
8763 if (old->x == new->x && old->y == new->y) {
\r
8767 /* Work out what bits overlap. Since we know the rects
\r
8768 are the same size we don't need a full intersect calc. */
\r
8770 /* Top or bottom edge? */
\r
8771 if (new->y > old->y) {
\r
8772 SetRect(&(update[count]), old->x, old->y, size, new->y - old->y);
\r
8774 } else if (old->y > new->y) {
\r
8775 SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y),
\r
8776 size, old->y - new->y);
\r
8779 /* Left or right edge - don't overlap any update calculated above. */
\r
8780 if (new->x > old->x) {
\r
8781 SetRect(&(update[count]), old->x, Max(new->y, old->y),
\r
8782 new->x - old->x, size - abs(new->y - old->y));
\r
8784 } else if (old->x > new->x) {
\r
8785 SetRect(&(update[count]), new->x + size, Max(new->y, old->y),
\r
8786 old->x - new->x, size - abs(new->y - old->y));
\r
8790 *nUpdates = count;
\r
8793 /* Generate a series of frame coords from start->mid->finish.
\r
8794 The movement rate doubles until the half way point is
\r
8795 reached, then halves back down to the final destination,
\r
8796 which gives a nice slow in/out effect. The algorithmn
\r
8797 may seem to generate too many intermediates for short
\r
8798 moves, but remember that the purpose is to attract the
\r
8799 viewers attention to the piece about to be moved and
\r
8800 then to where it ends up. Too few frames would be less
\r
8804 Tween(start, mid, finish, factor, frames, nFrames)
\r
8805 XPoint * start; XPoint * mid;
\r
8806 XPoint * finish; int factor;
\r
8807 XPoint frames[]; int * nFrames;
\r
8809 int fraction, n, count;
\r
8813 /* Slow in, stepping 1/16th, then 1/8th, ... */
\r
8815 for (n = 0; n < factor; n++)
\r
8817 for (n = 0; n < factor; n++) {
\r
8818 frames[count].x = start->x + (mid->x - start->x) / fraction;
\r
8819 frames[count].y = start->y + (mid->y - start->y) / fraction;
\r
8821 fraction = fraction / 2;
\r
8825 frames[count] = *mid;
\r
8828 /* Slow out, stepping 1/2, then 1/4, ... */
\r
8830 for (n = 0; n < factor; n++) {
\r
8831 frames[count].x = finish->x - (finish->x - mid->x) / fraction;
\r
8832 frames[count].y = finish->y - (finish->y - mid->y) / fraction;
\r
8834 fraction = fraction * 2;
\r
8839 /* Draw a piece on the screen without disturbing what's there */
\r
8842 SelectGCMask(piece, clip, outline, mask)
\r
8843 ChessSquare piece; GC * clip; GC * outline; Pixmap * mask;
\r
8847 /* Bitmap for piece being moved. */
\r
8848 if (appData.monoMode) {
\r
8849 *mask = *pieceToSolid(piece);
\r
8850 } else if (useImages) {
\r
8852 *mask = xpmMask[piece];
\r
8854 *mask = ximMaskPm[piece%(int)BlackPawn];
\r
8857 *mask = *pieceToSolid(piece);
\r
8860 /* GC for piece being moved. Square color doesn't matter, but
\r
8861 since it gets modified we make a copy of the original. */
\r
8862 if (White(piece)) {
\r
8863 if (appData.monoMode)
\r
8864 source = bwPieceGC;
\r
8866 source = wlPieceGC;
\r
8868 if (appData.monoMode)
\r
8869 source = wbPieceGC;
\r
8871 source = blPieceGC;
\r
8873 XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
\r
8875 /* Outline only used in mono mode and is not modified */
\r
8877 *outline = bwPieceGC;
\r
8879 *outline = wbPieceGC;
\r
8883 OverlayPiece(piece, clip, outline, dest)
\r
8884 ChessSquare piece; GC clip; GC outline; Drawable dest;
\r
8889 /* Draw solid rectangle which will be clipped to shape of piece */
\r
8890 XFillRectangle(xDisplay, dest, clip,
\r
8891 0, 0, squareSize, squareSize);
\r
8892 if (appData.monoMode)
\r
8893 /* Also draw outline in contrasting color for black
\r
8894 on black / white on white cases */
\r
8895 XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
\r
8896 0, 0, squareSize, squareSize, 0, 0, 1);
\r
8898 /* Copy the piece */
\r
8903 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
\r
8905 0, 0, squareSize, squareSize,
\r
8910 /* Animate the movement of a single piece */
\r
8913 BeginAnimation(anim, piece, startColor, start)
\r
8915 ChessSquare piece;
\r
8921 /* The old buffer is initialised with the start square (empty) */
\r
8922 BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);
\r
8923 anim->prevFrame = *start;
\r
8925 /* The piece will be drawn using its own bitmap as a matte */
\r
8926 SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
\r
8927 XSetClipMask(xDisplay, anim->pieceGC, mask);
\r
8931 AnimationFrame(anim, frame, piece)
\r
8934 ChessSquare piece;
\r
8936 XRectangle updates[4];
\r
8937 XRectangle overlap;
\r
8941 /* Save what we are about to draw into the new buffer */
\r
8942 XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
\r
8943 frame->x, frame->y, squareSize, squareSize,
\r
8946 /* Erase bits of the previous frame */
\r
8947 if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {
\r
8948 /* Where the new frame overlapped the previous,
\r
8949 the contents in newBuf are wrong. */
\r
8950 XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
\r
8951 overlap.x, overlap.y,
\r
8952 overlap.width, overlap.height,
\r
8954 /* Repaint the areas in the old that don't overlap new */
\r
8955 CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);
\r
8956 for (i = 0; i < count; i++)
\r
8957 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8958 updates[i].x - anim->prevFrame.x,
\r
8959 updates[i].y - anim->prevFrame.y,
\r
8960 updates[i].width, updates[i].height,
\r
8961 updates[i].x, updates[i].y);
\r
8963 /* Easy when no overlap */
\r
8964 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8965 0, 0, squareSize, squareSize,
\r
8966 anim->prevFrame.x, anim->prevFrame.y);
\r
8969 /* Save this frame for next time round */
\r
8970 XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
\r
8971 0, 0, squareSize, squareSize,
\r
8973 anim->prevFrame = *frame;
\r
8975 /* Draw piece over original screen contents, not current,
\r
8976 and copy entire rect. Wipes out overlapping piece images. */
\r
8977 OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);
\r
8978 XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
\r
8979 0, 0, squareSize, squareSize,
\r
8980 frame->x, frame->y);
\r
8984 EndAnimation (anim, finish)
\r
8988 XRectangle updates[4];
\r
8989 XRectangle overlap;
\r
8993 /* The main code will redraw the final square, so we
\r
8994 only need to erase the bits that don't overlap. */
\r
8995 if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {
\r
8996 CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);
\r
8997 for (i = 0; i < count; i++)
\r
8998 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8999 updates[i].x - anim->prevFrame.x,
\r
9000 updates[i].y - anim->prevFrame.y,
\r
9001 updates[i].width, updates[i].height,
\r
9002 updates[i].x, updates[i].y);
\r
9004 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
9005 0, 0, squareSize, squareSize,
\r
9006 anim->prevFrame.x, anim->prevFrame.y);
\r
9011 FrameSequence(anim, piece, startColor, start, finish, frames, nFrames)
\r
9013 ChessSquare piece; int startColor;
\r
9014 XPoint * start; XPoint * finish;
\r
9015 XPoint frames[]; int nFrames;
\r
9019 BeginAnimation(anim, piece, startColor, start);
\r
9020 for (n = 0; n < nFrames; n++) {
\r
9021 AnimationFrame(anim, &(frames[n]), piece);
\r
9022 FrameDelay(appData.animSpeed);
\r
9024 EndAnimation(anim, finish);
\r
9027 /* Main control logic for deciding what to animate and how */
\r
9030 AnimateMove(board, fromX, fromY, toX, toY)
\r
9037 ChessSquare piece;
\r
9039 XPoint start, finish, mid;
\r
9040 XPoint frames[kFactor * 2 + 1];
\r
9041 int nFrames, startColor, endColor;
\r
9043 /* Are we animating? */
\r
9044 if (!appData.animate || appData.blindfold)
\r
9047 if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
\r
9048 piece = board[fromY][fromX];
\r
9049 if (piece >= EmptySquare) return;
\r
9054 hop = (piece == WhiteKnight || piece == BlackKnight);
\r
9057 if (appData.debugMode) {
\r
9058 fprintf(debugFP, hop ? _("AnimateMove: piece %d hops from %d,%d to %d,%d \n") :
\r
9059 _("AnimateMove: piece %d slides from %d,%d to %d,%d \n"),
\r
9060 piece, fromX, fromY, toX, toY); }
\r
9062 ScreenSquare(fromX, fromY, &start, &startColor);
\r
9063 ScreenSquare(toX, toY, &finish, &endColor);
\r
9066 /* Knight: make diagonal movement then straight */
\r
9067 if (abs(toY - fromY) < abs(toX - fromX)) {
\r
9068 mid.x = start.x + (finish.x - start.x) / 2;
\r
9072 mid.y = start.y + (finish.y - start.y) / 2;
\r
9075 mid.x = start.x + (finish.x - start.x) / 2;
\r
9076 mid.y = start.y + (finish.y - start.y) / 2;
\r
9079 /* Don't use as many frames for very short moves */
\r
9080 if (abs(toY - fromY) + abs(toX - fromX) <= 2)
\r
9081 Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);
\r
9083 Tween(&start, &mid, &finish, kFactor, frames, &nFrames);
\r
9084 FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
\r
9086 /* Be sure end square is redrawn */
\r
9087 damage[toY][toX] = True;
\r
9091 DragPieceBegin(x, y)
\r
9094 int boardX, boardY, color;
\r
9097 /* Are we animating? */
\r
9098 if (!appData.animateDragging || appData.blindfold)
\r
9101 /* Figure out which square we start in and the
\r
9102 mouse position relative to top left corner. */
\r
9103 BoardSquare(x, y, &boardX, &boardY);
\r
9104 player.startBoardX = boardX;
\r
9105 player.startBoardY = boardY;
\r
9106 ScreenSquare(boardX, boardY, &corner, &color);
\r
9107 player.startSquare = corner;
\r
9108 player.startColor = color;
\r
9110 /* Start from exactly where the piece is. This can be confusing
\r
9111 if you start dragging far from the center of the square; most
\r
9112 or all of the piece can be over a different square from the one
\r
9113 the mouse pointer is in. */
\r
9114 player.mouseDelta.x = x - corner.x;
\r
9115 player.mouseDelta.y = y - corner.y;
\r
9117 /* As soon as we start dragging, the piece will jump slightly to
\r
9118 be centered over the mouse pointer. */
\r
9119 player.mouseDelta.x = squareSize/2;
\r
9120 player.mouseDelta.y = squareSize/2;
\r
9122 /* Initialise animation */
\r
9123 player.dragPiece = PieceForSquare(boardX, boardY);
\r
9124 /* Sanity check */
\r
9125 if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {
\r
9126 player.dragActive = True;
\r
9127 BeginAnimation(&player, player.dragPiece, color, &corner);
\r
9128 /* Mark this square as needing to be redrawn. Note that
\r
9129 we don't remove the piece though, since logically (ie
\r
9130 as seen by opponent) the move hasn't been made yet. */
\r
9131 damage[boardY][boardX] = True;
\r
9133 player.dragActive = False;
\r
9138 DragPieceMove(x, y)
\r
9143 /* Are we animating? */
\r
9144 if (!appData.animateDragging || appData.blindfold)
\r
9147 /* Sanity check */
\r
9148 if (! player.dragActive)
\r
9150 /* Move piece, maintaining same relative position
\r
9151 of mouse within square */
\r
9152 corner.x = x - player.mouseDelta.x;
\r
9153 corner.y = y - player.mouseDelta.y;
\r
9154 AnimationFrame(&player, &corner, player.dragPiece);
\r
9156 if (appData.highlightDragging) {
\r
9157 int boardX, boardY;
\r
9158 BoardSquare(x, y, &boardX, &boardY);
\r
9159 SetHighlights(fromX, fromY, boardX, boardY);
\r
9165 DragPieceEnd(x, y)
\r
9168 int boardX, boardY, color;
\r
9171 /* Are we animating? */
\r
9172 if (!appData.animateDragging || appData.blindfold)
\r
9175 /* Sanity check */
\r
9176 if (! player.dragActive)
\r
9178 /* Last frame in sequence is square piece is
\r
9179 placed on, which may not match mouse exactly. */
\r
9180 BoardSquare(x, y, &boardX, &boardY);
\r
9181 ScreenSquare(boardX, boardY, &corner, &color);
\r
9182 EndAnimation(&player, &corner);
\r
9184 /* Be sure end square is redrawn */
\r
9185 damage[boardY][boardX] = True;
\r
9187 /* This prevents weird things happening with fast successive
\r
9188 clicks which on my Sun at least can cause motion events
\r
9189 without corresponding press/release. */
\r
9190 player.dragActive = False;
\r
9193 /* Handle expose event while piece being dragged */
\r
9198 if (!player.dragActive || appData.blindfold)
\r
9201 /* What we're doing: logically, the move hasn't been made yet,
\r
9202 so the piece is still in it's original square. But visually
\r
9203 it's being dragged around the board. So we erase the square
\r
9204 that the piece is on and draw it at the last known drag point. */
\r
9205 BlankSquare(player.startSquare.x, player.startSquare.y,
\r
9206 player.startColor, EmptySquare, xBoardWindow);
\r
9207 AnimationFrame(&player, &player.prevFrame, player.dragPiece);
\r
9208 damage[player.startBoardY][player.startBoardX] = TRUE;
\r
9212 SetProgramStats( FrontEndProgramStats * stats )
\r
9215 // [HGM] done, but perhaps backend should call this directly?
\r
9216 EngineOutputUpdate( stats );
\r