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,
\r
6 * Massachusetts. Enhancements Copyright
\r
7 * 1992-2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software
\r
10 * The following terms apply to Digital Equipment Corporation's copyright
\r
11 * interest in XBoard:
\r
12 * ------------------------------------------------------------------------
\r
13 * All Rights Reserved
\r
15 * Permission to use, copy, modify, and distribute this software and its
\r
16 * documentation for any purpose and without fee is hereby granted,
\r
17 * provided that the above copyright notice appear in all copies and that
\r
18 * both that copyright notice and this permission notice appear in
\r
19 * supporting documentation, and that the name of Digital not be
\r
20 * used in advertising or publicity pertaining to distribution of the
\r
21 * software without specific, written prior permission.
\r
23 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
\r
24 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
\r
25 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
\r
26 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
\r
27 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
\r
28 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
\r
30 * ------------------------------------------------------------------------
\r
32 * The following terms apply to the enhanced version of XBoard
\r
33 * distributed by the Free Software Foundation:
\r
34 * ------------------------------------------------------------------------
\r
36 * GNU XBoard is free software: you can redistribute it and/or modify
\r
37 * it under the terms of the GNU General Public License as published by
\r
38 * the Free Software Foundation, either version 3 of the License, or (at
\r
39 * your option) any later version.
\r
41 * GNU XBoard is distributed in the hope that it will be useful, but
\r
42 * WITHOUT ANY WARRANTY; without even the implied warranty of
\r
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
44 * General Public License for more details.
\r
46 * You should have received a copy of the GNU General Public License
\r
47 * along with this program. If not, see http://www.gnu.org/licenses/. *
\r
49 *------------------------------------------------------------------------
\r
50 ** See the file ChangeLog for a revision history. */
\r
58 #include <sys/types.h>
\r
59 #include <sys/stat.h>
\r
63 # if HAVE_SYS_SOCKET_H
\r
64 # include <sys/socket.h>
\r
65 # include <netinet/in.h>
\r
67 # else /* not HAVE_SYS_SOCKET_H */
\r
68 # if HAVE_LAN_SOCKET_H
\r
69 # include <lan/socket.h>
\r
70 # include <lan/in.h>
\r
71 # include <lan/netdb.h>
\r
72 # else /* not HAVE_LAN_SOCKET_H */
\r
73 # define OMIT_SOCKETS 1
\r
74 # endif /* not HAVE_LAN_SOCKET_H */
\r
75 # endif /* not HAVE_SYS_SOCKET_H */
\r
76 #endif /* !OMIT_SOCKETS */
\r
79 # include <stdlib.h>
\r
80 # include <string.h>
\r
81 #else /* not STDC_HEADERS */
\r
82 extern char *getenv();
\r
84 # include <string.h>
\r
85 # else /* not HAVE_STRING_H */
\r
86 # include <strings.h>
\r
87 # endif /* not HAVE_STRING_H */
\r
88 #endif /* not STDC_HEADERS */
\r
90 #if HAVE_SYS_FCNTL_H
\r
91 # include <sys/fcntl.h>
\r
92 #else /* not HAVE_SYS_FCNTL_H */
\r
95 # endif /* HAVE_FCNTL_H */
\r
96 #endif /* not HAVE_SYS_FCNTL_H */
\r
98 #if HAVE_SYS_SYSTEMINFO_H
\r
99 # include <sys/systeminfo.h>
\r
100 #endif /* HAVE_SYS_SYSTEMINFO_H */
\r
102 #if TIME_WITH_SYS_TIME
\r
103 # include <sys/time.h>
\r
106 # if HAVE_SYS_TIME_H
\r
107 # include <sys/time.h>
\r
114 # include <unistd.h>
\r
117 #if HAVE_SYS_WAIT_H
\r
118 # include <sys/wait.h>
\r
122 # include <dirent.h>
\r
123 # define NAMLEN(dirent) strlen((dirent)->d_name)
\r
124 # define HAVE_DIR_STRUCT
\r
126 # define dirent direct
\r
127 # define NAMLEN(dirent) (dirent)->d_namlen
\r
128 # if HAVE_SYS_NDIR_H
\r
129 # include <sys/ndir.h>
\r
130 # define HAVE_DIR_STRUCT
\r
132 # if HAVE_SYS_DIR_H
\r
133 # include <sys/dir.h>
\r
134 # define HAVE_DIR_STRUCT
\r
138 # define HAVE_DIR_STRUCT
\r
142 #include <X11/Intrinsic.h>
\r
143 #include <X11/StringDefs.h>
\r
144 #include <X11/Shell.h>
\r
145 #include <X11/cursorfont.h>
\r
146 #include <X11/Xatom.h>
\r
148 #include <X11/Xaw3d/Dialog.h>
\r
149 #include <X11/Xaw3d/Form.h>
\r
150 #include <X11/Xaw3d/List.h>
\r
151 #include <X11/Xaw3d/Label.h>
\r
152 #include <X11/Xaw3d/SimpleMenu.h>
\r
153 #include <X11/Xaw3d/SmeBSB.h>
\r
154 #include <X11/Xaw3d/SmeLine.h>
\r
155 #include <X11/Xaw3d/Box.h>
\r
156 #include <X11/Xaw3d/MenuButton.h>
\r
157 #include <X11/Xaw3d/Text.h>
\r
158 #include <X11/Xaw3d/AsciiText.h>
\r
160 #include <X11/Xaw/Dialog.h>
\r
161 #include <X11/Xaw/Form.h>
\r
162 #include <X11/Xaw/List.h>
\r
163 #include <X11/Xaw/Label.h>
\r
164 #include <X11/Xaw/SimpleMenu.h>
\r
165 #include <X11/Xaw/SmeBSB.h>
\r
166 #include <X11/Xaw/SmeLine.h>
\r
167 #include <X11/Xaw/Box.h>
\r
168 #include <X11/Xaw/MenuButton.h>
\r
169 #include <X11/Xaw/Text.h>
\r
170 #include <X11/Xaw/AsciiText.h>
\r
173 // [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
\r
174 #include "common.h"
\r
177 #include <X11/xpm.h>
\r
178 #include "pixmaps/pixmaps.h"
\r
179 #define IMAGE_EXT "xpm"
\r
181 #define IMAGE_EXT "xim"
\r
182 #include "bitmaps/bitmaps.h"
\r
185 #include "bitmaps/icon_white.bm"
\r
186 #include "bitmaps/icon_black.bm"
\r
187 #include "bitmaps/checkmark.bm"
\r
189 #include "frontend.h"
\r
190 #include "backend.h"
\r
192 #include "xboard.h"
\r
193 #include "childio.h"
\r
194 #include "xgamelist.h"
\r
195 #include "xhistory.h"
\r
196 #include "xedittags.h"
\r
197 #include "gettext.h"
\r
199 // must be moved to xengineoutput.h
\r
201 void EngineOutputProc P((Widget w, XEvent *event,
\r
202 String *prms, Cardinal *nprms));
\r
204 void EngineOutputPopDown();
\r
208 #ifndef HAVE_USLEEP
\r
209 #define HAVE_USLEEP
\r
211 #define usleep(t) _sleep2(((t)+500)/1000)
\r
215 # define _(s) gettext (s)
\r
216 # define N_(s) gettext_noop (s)
\r
232 int main P((int argc, char **argv));
\r
233 RETSIGTYPE CmailSigHandler P((int sig));
\r
234 RETSIGTYPE IntSigHandler P((int sig));
\r
235 void CreateGCs P((void));
\r
236 void CreateXIMPieces P((void));
\r
237 void CreateXPMPieces P((void));
\r
238 void CreatePieces P((void));
\r
239 void CreatePieceMenus P((void));
\r
240 Widget CreateMenuBar P((Menu *mb));
\r
241 Widget CreateButtonBar P ((MenuItem *mi));
\r
242 char *FindFont P((char *pattern, int targetPxlSize));
\r
243 void PieceMenuPopup P((Widget w, XEvent *event,
\r
244 String *params, Cardinal *num_params));
\r
245 static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
\r
246 static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
\r
247 void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
\r
248 u_int wreq, u_int hreq));
\r
249 void CreateGrid P((void));
\r
250 int EventToSquare P((int x, int limit));
\r
251 void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
\r
252 void EventProc P((Widget widget, caddr_t unused, XEvent *event));
\r
253 void HandleUserMove P((Widget w, XEvent *event,
\r
254 String *prms, Cardinal *nprms));
\r
255 void AnimateUserMove P((Widget w, XEvent * event,
\r
256 String * params, Cardinal * nParams));
\r
257 void WhiteClock P((Widget w, XEvent *event,
\r
258 String *prms, Cardinal *nprms));
\r
259 void BlackClock P((Widget w, XEvent *event,
\r
260 String *prms, Cardinal *nprms));
\r
261 void DrawPositionProc P((Widget w, XEvent *event,
\r
262 String *prms, Cardinal *nprms));
\r
263 void XDrawPosition P((Widget w, /*Boolean*/int repaint,
\r
265 void CommentPopUp P((char *title, char *label));
\r
266 void CommentPopDown P((void));
\r
267 void CommentCallback P((Widget w, XtPointer client_data,
\r
268 XtPointer call_data));
\r
269 void ICSInputBoxPopUp P((void));
\r
270 void ICSInputBoxPopDown P((void));
\r
271 void FileNamePopUp P((char *label, char *def,
\r
272 FileProc proc, char *openMode));
\r
273 void FileNamePopDown P((void));
\r
274 void FileNameCallback P((Widget w, XtPointer client_data,
\r
275 XtPointer call_data));
\r
276 void FileNameAction P((Widget w, XEvent *event,
\r
277 String *prms, Cardinal *nprms));
\r
278 void AskQuestionReplyAction P((Widget w, XEvent *event,
\r
279 String *prms, Cardinal *nprms));
\r
280 void AskQuestionProc P((Widget w, XEvent *event,
\r
281 String *prms, Cardinal *nprms));
\r
282 void AskQuestionPopDown P((void));
\r
283 void PromotionPopUp P((void));
\r
284 void PromotionPopDown P((void));
\r
285 void PromotionCallback P((Widget w, XtPointer client_data,
\r
286 XtPointer call_data));
\r
287 void EditCommentPopDown P((void));
\r
288 void EditCommentCallback P((Widget w, XtPointer client_data,
\r
289 XtPointer call_data));
\r
290 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
\r
291 void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
292 void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
293 void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
\r
295 void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
\r
297 void ReloadGameProc P((Widget w, XEvent *event, String *prms,
\r
299 void LoadPositionProc P((Widget w, XEvent *event,
\r
300 String *prms, Cardinal *nprms));
\r
301 void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
\r
303 void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
\r
305 void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
\r
307 void CopyPositionProc P((Widget w, XEvent *event, String *prms,
\r
309 void PastePositionProc P((Widget w, XEvent *event, String *prms,
\r
311 void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
312 void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
313 void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
314 void SavePositionProc P((Widget w, XEvent *event,
\r
315 String *prms, Cardinal *nprms));
\r
316 void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
317 void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
\r
319 void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
320 void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
321 void MachineBlackProc P((Widget w, XEvent *event, String *prms,
\r
323 void MachineWhiteProc P((Widget w, XEvent *event,
\r
324 String *prms, Cardinal *nprms));
\r
325 void AnalyzeModeProc P((Widget w, XEvent *event,
\r
326 String *prms, Cardinal *nprms));
\r
327 void AnalyzeFileProc P((Widget w, XEvent *event,
\r
328 String *prms, Cardinal *nprms));
\r
329 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
\r
331 void IcsClientProc P((Widget w, XEvent *event, String *prms,
\r
333 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
334 void EditPositionProc P((Widget w, XEvent *event,
\r
335 String *prms, Cardinal *nprms));
\r
336 void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
337 void EditCommentProc P((Widget w, XEvent *event,
\r
338 String *prms, Cardinal *nprms));
\r
339 void IcsInputBoxProc P((Widget w, XEvent *event,
\r
340 String *prms, Cardinal *nprms));
\r
341 void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
342 void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
343 void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
344 void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
345 void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
346 void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
347 void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
348 void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
349 void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
350 void StopObservingProc P((Widget w, XEvent *event, String *prms,
\r
352 void StopExaminingProc P((Widget w, XEvent *event, String *prms,
\r
354 void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
355 void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
356 void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
357 void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
358 void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
359 void TruncateGameProc P((Widget w, XEvent *event, String *prms,
\r
361 void RetractMoveProc P((Widget w, XEvent *event, String *prms,
\r
363 void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
364 void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
\r
366 void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
\r
368 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
\r
370 void AutocommProc P((Widget w, XEvent *event, String *prms,
\r
372 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
373 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
374 void AutobsProc P((Widget w, XEvent *event, String *prms,
\r
376 void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
377 void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
378 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
379 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
\r
381 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
382 void GetMoveListProc P((Widget w, XEvent *event, String *prms,
\r
384 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
\r
386 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
\r
388 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
389 void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
390 void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
\r
392 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
\r
394 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
\r
396 void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
\r
398 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
\r
400 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
401 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
402 void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
\r
404 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
\r
406 void HideThinkingProc P((Widget w, XEvent *event, String *prms,
\r
408 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
\r
410 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
411 void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
412 void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
413 void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
414 void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
415 void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
416 void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
417 void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
418 void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
419 void DisplayMove P((int moveNumber));
\r
420 void DisplayTitle P((char *title));
\r
421 void ICSInitScript P((void));
\r
422 int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
\r
423 void ErrorPopUp P((char *title, char *text, int modal));
\r
424 void ErrorPopDown P((void));
\r
425 static char *ExpandPathName P((char *path));
\r
426 static void CreateAnimVars P((void));
\r
427 static void DragPieceBegin P((int x, int y));
\r
428 static void DragPieceMove P((int x, int y));
\r
429 static void DragPieceEnd P((int x, int y));
\r
430 static void DrawDragPiece P((void));
\r
431 char *ModeToWidgetName P((GameMode mode));
\r
432 void EngineOutputUpdate( FrontEndProgramStats * stats );
\r
433 void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
434 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
435 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
436 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
437 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
438 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
439 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
440 void ShufflePopDown P(());
\r
441 void EnginePopDown P(());
\r
442 void UciPopDown P(());
\r
443 void TimeControlPopDown P(());
\r
444 void NewVariantPopDown P(());
\r
445 void SettingsPopDown P(());
\r
447 * XBoard depends on Xt R4 or higher
\r
449 int xtVersion = XtSpecificationRelease;
\r
453 Window xBoardWindow;
\r
454 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
\r
455 jailSquareColor, highlightSquareColor, premoveHighlightColor;
\r
456 GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
\r
457 bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
\r
458 wjPieceGC, bjPieceGC, prelineGC, countGC;
\r
459 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
\r
460 Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
\r
461 whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
\r
462 commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
\r
463 menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
\r
464 ICSInputShell, fileNameShell, askQuestionShell;
\r
465 XSegment gridSegments[(BOARD_SIZE + 1) * 2];
\r
466 XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
\r
467 Font clockFontID, coordFontID, countFontID;
\r
468 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
\r
469 XtAppContext appContext;
\r
471 char *oldICSInteractionTitle;
\r
474 char *fileOpenMode;
\r
475 char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
\r
477 Position commentX = -1, commentY = -1;
\r
478 Dimension commentW, commentH;
\r
480 int squareSize, smallLayout = 0, tinyLayout = 0,
\r
481 marginW, marginH, // [HGM] for run-time resizing
\r
482 fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
\r
483 ICSInputBoxUp = False, askQuestionUp = False,
\r
484 filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
\r
485 editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
\r
486 Pixel timerForegroundPixel, timerBackgroundPixel;
\r
487 Pixel buttonForegroundPixel, buttonBackgroundPixel;
\r
488 char *chessDir, *programName, *programVersion,
\r
489 *gameCopyFilename, *gamePasteFilename;
\r
493 Pixmap pieceBitmap[2][(int)BlackPawn];
\r
494 Pixmap xpmPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */
\r
495 Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
\r
496 int useImages, useImageSqs;
\r
497 XImage *ximPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */
\r
498 Pixmap ximMaskPm[(int)BlackPawn]; /* clipmasks, used for XIM pieces */
\r
499 XImage *ximLightSquare, *ximDarkSquare;
\r
502 #define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % (int)BlackPawn]
\r
503 #define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % (int)BlackPawn]
\r
505 #define White(piece) ((int)(piece) < (int)BlackPawn)
\r
507 /* Variables for doing smooth animation. This whole thing
\r
508 would be much easier if the board was double-buffered,
\r
509 but that would require a fairly major rewrite. */
\r
514 GC blitGC, pieceGC, outlineGC;
\r
515 XPoint startSquare, prevFrame, mouseDelta;
\r
518 Boolean dragActive;
\r
519 int startBoardX, startBoardY;
\r
522 /* There can be two pieces being animated at once: a player
\r
523 can begin dragging a piece before the remote opponent has moved. */
\r
525 static AnimState game, player;
\r
527 /* Bitmaps for use as masks when drawing XPM pieces.
\r
528 Need one for each black and white piece. */
\r
529 static Pixmap xpmMask[BlackKing + 1];
\r
531 /* This magic number is the number of intermediate frames used
\r
532 in each half of the animation. For short moves it's reduced
\r
533 by 1. The total number of frames will be factor * 2 + 1. */
\r
536 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
\r
538 MenuItem fileMenu[] = {
\r
539 {N_("New Game"), ResetProc},
\r
540 {N_("New Shuffle Game ..."), ShuffleMenuProc},
\r
541 {N_("New Variant ..."), NewVariantProc}, // [HGM] variant: not functional yet
\r
542 {"----", NothingProc},
\r
543 {N_("Load Game"), LoadGameProc},
\r
544 {N_("Load Next Game"), LoadNextGameProc},
\r
545 {N_("Load Previous Game"), LoadPrevGameProc},
\r
546 {N_("Reload Same Game"), ReloadGameProc},
\r
547 {N_("Save Game"), SaveGameProc},
\r
548 {"----", NothingProc},
\r
549 {N_("Copy Game"), CopyGameProc},
\r
550 {N_("Paste Game"), PasteGameProc},
\r
551 {"----", NothingProc},
\r
552 {N_("Load Position"), LoadPositionProc},
\r
553 {N_("Load Next Position"), LoadNextPositionProc},
\r
554 {N_("Load Previous Position"), LoadPrevPositionProc},
\r
555 {N_("Reload Same Position"), ReloadPositionProc},
\r
556 {N_("Save Position"), SavePositionProc},
\r
557 {"----", NothingProc},
\r
558 {N_("Copy Position"), CopyPositionProc},
\r
559 {N_("Paste Position"), PastePositionProc},
\r
560 {"----", NothingProc},
\r
561 {N_("Mail Move"), MailMoveProc},
\r
562 {N_("Reload CMail Message"), ReloadCmailMsgProc},
\r
563 {"----", NothingProc},
\r
564 {N_("Exit"), QuitProc},
\r
568 MenuItem modeMenu[] = {
\r
569 {N_("Machine White"), MachineWhiteProc},
\r
570 {N_("Machine Black"), MachineBlackProc},
\r
571 {N_("Two Machines"), TwoMachinesProc},
\r
572 {N_("Analysis Mode"), AnalyzeModeProc},
\r
573 {N_("Analyze File"), AnalyzeFileProc },
\r
574 {N_("ICS Client"), IcsClientProc},
\r
575 {N_("Edit Game"), EditGameProc},
\r
576 {N_("Edit Position"), EditPositionProc},
\r
577 {N_("Training"), TrainingProc},
\r
578 {"----", NothingProc},
\r
579 {N_("Show Engine Output"), EngineOutputProc},
\r
580 {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
\r
581 {N_("Show Game List"), ShowGameListProc},
\r
582 {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
\r
583 {"----", NothingProc},
\r
584 {N_("Edit Tags"), EditTagsProc},
\r
585 {N_("Edit Comment"), EditCommentProc},
\r
586 {N_("ICS Input Box"), IcsInputBoxProc},
\r
587 {N_("Pause"), PauseProc},
\r
591 MenuItem actionMenu[] = {
\r
592 {N_("Accept"), AcceptProc},
\r
593 {N_("Decline"), DeclineProc},
\r
594 {N_("Rematch"), RematchProc},
\r
595 {"----", NothingProc},
\r
596 {N_("Call Flag"), CallFlagProc},
\r
597 {N_("Draw"), DrawProc},
\r
598 {N_("Adjourn"), AdjournProc},
\r
599 {N_("Abort"), AbortProc},
\r
600 {N_("Resign"), ResignProc},
\r
601 {"----", NothingProc},
\r
602 {N_("Stop Observing"), StopObservingProc},
\r
603 {N_("Stop Examining"), StopExaminingProc},
\r
607 MenuItem stepMenu[] = {
\r
608 {N_("Backward"), BackwardProc},
\r
609 {N_("Forward"), ForwardProc},
\r
610 {N_("Back to Start"), ToStartProc},
\r
611 {N_("Forward to End"), ToEndProc},
\r
612 {N_("Revert"), RevertProc},
\r
613 {N_("Truncate Game"), TruncateGameProc},
\r
614 {"----", NothingProc},
\r
615 {N_("Move Now"), MoveNowProc},
\r
616 {N_("Retract Move"), RetractMoveProc},
\r
620 MenuItem optionsMenu[] = {
\r
621 {N_("Flip View"), FlipViewProc},
\r
622 {"----", NothingProc},
\r
623 {N_("Adjudications ..."), EngineMenuProc},
\r
624 {N_("General Settings ..."), UciMenuProc},
\r
625 {N_("Engine #1 Settings ..."), FirstSettingsProc},
\r
626 {N_("Engine #2 Settings ..."), SecondSettingsProc},
\r
627 {N_("Time Control ..."), TimeControlProc},
\r
628 {"----", NothingProc},
\r
629 {N_("Always Queen"), AlwaysQueenProc},
\r
630 {N_("Animate Dragging"), AnimateDraggingProc},
\r
631 {N_("Animate Moving"), AnimateMovingProc},
\r
632 {N_("Auto Comment"), AutocommProc},
\r
633 {N_("Auto Flag"), AutoflagProc},
\r
634 {N_("Auto Flip View"), AutoflipProc},
\r
635 {N_("Auto Observe"), AutobsProc},
\r
636 {N_("Auto Raise Board"), AutoraiseProc},
\r
637 {N_("Auto Save"), AutosaveProc},
\r
638 {N_("Blindfold"), BlindfoldProc},
\r
639 {N_("Flash Moves"), FlashMovesProc},
\r
640 {N_("Get Move List"), GetMoveListProc},
\r
642 {N_("Highlight Dragging"), HighlightDraggingProc},
\r
644 {N_("Highlight Last Move"), HighlightLastMoveProc},
\r
645 {N_("Move Sound"), MoveSoundProc},
\r
646 {N_("ICS Alarm"), IcsAlarmProc},
\r
647 {N_("Old Save Style"), OldSaveStyleProc},
\r
648 {N_("Periodic Updates"), PeriodicUpdatesProc},
\r
649 {N_("Ponder Next Move"), PonderNextMoveProc},
\r
650 {N_("Popup Exit Message"), PopupExitMessageProc},
\r
651 {N_("Popup Move Errors"), PopupMoveErrorsProc},
\r
652 {N_("Premove"), PremoveProc},
\r
653 {N_("Quiet Play"), QuietPlayProc},
\r
654 {N_("Show Coords"), ShowCoordsProc},
\r
655 {N_("Hide Thinking"), HideThinkingProc},
\r
656 {N_("Test Legality"), TestLegalityProc},
\r
660 MenuItem helpMenu[] = {
\r
661 {N_("Info XBoard"), InfoProc},
\r
662 {N_("Man XBoard"), ManProc},
\r
663 {"----", NothingProc},
\r
664 {N_("Hint"), HintProc},
\r
665 {N_("Book"), BookProc},
\r
666 {"----", NothingProc},
\r
667 {N_("About XBoard"), AboutProc},
\r
672 {N_("File"), fileMenu},
\r
673 {N_("Mode"), modeMenu},
\r
674 {N_("Action"), actionMenu},
\r
675 {N_("Step"), stepMenu},
\r
676 {N_("Options"), optionsMenu},
\r
677 {N_("Help"), helpMenu},
\r
681 #define PAUSE_BUTTON N_("P")
\r
682 MenuItem buttonBar[] = {
\r
683 {"<<", ToStartProc},
\r
684 {"<", BackwardProc},
\r
685 {PAUSE_BUTTON, PauseProc},
\r
686 {">", ForwardProc},
\r
691 #define PIECE_MENU_SIZE 11
\r
692 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
\r
693 { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
\r
694 N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
\r
695 { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
\r
696 N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
\r
698 /* must be in same order as PieceMenuStrings! */
\r
699 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
\r
700 { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
\r
701 WhiteRook, WhiteQueen, WhiteKing,
\r
702 (ChessSquare) 0, EmptySquare, ClearBoard },
\r
703 { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
\r
704 BlackRook, BlackQueen, BlackKing,
\r
705 (ChessSquare) 0, EmptySquare, ClearBoard },
\r
708 #define DROP_MENU_SIZE 6
\r
709 String dropMenuStrings[DROP_MENU_SIZE] = {
\r
710 "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
\r
712 /* must be in same order as PieceMenuStrings! */
\r
713 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
\r
714 (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
\r
715 WhiteRook, WhiteQueen
\r
723 DropMenuEnables dmEnables[] = {
\r
731 Arg shellArgs[] = {
\r
734 { XtNminWidth, 0 },
\r
735 { XtNminHeight, 0 },
\r
736 { XtNmaxWidth, 0 },
\r
737 { XtNmaxHeight, 0 }
\r
740 Arg layoutArgs[] = {
\r
741 { XtNborderWidth, 0 },
\r
742 { XtNdefaultDistance, 0 },
\r
746 { XtNborderWidth, 0 },
\r
747 { XtNresizable, (XtArgVal) True },
\r
750 Arg boardArgs[] = {
\r
751 { XtNborderWidth, 0 },
\r
756 Arg titleArgs[] = {
\r
757 { XtNjustify, (XtArgVal) XtJustifyRight },
\r
758 { XtNlabel, (XtArgVal) "..." },
\r
759 { XtNresizable, (XtArgVal) True },
\r
760 { XtNresize, (XtArgVal) False }
\r
763 Arg messageArgs[] = {
\r
764 { XtNjustify, (XtArgVal) XtJustifyLeft },
\r
765 { XtNlabel, (XtArgVal) "..." },
\r
766 { XtNresizable, (XtArgVal) True },
\r
767 { XtNresize, (XtArgVal) False }
\r
770 Arg timerArgs[] = {
\r
771 { XtNborderWidth, 0 },
\r
772 { XtNjustify, (XtArgVal) XtJustifyLeft }
\r
775 XtResource clientResources[] = {
\r
776 { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
\r
777 XtOffset(AppDataPtr, whitePieceColor), XtRString,
\r
778 WHITE_PIECE_COLOR },
\r
779 { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
\r
780 XtOffset(AppDataPtr, blackPieceColor), XtRString,
\r
781 BLACK_PIECE_COLOR },
\r
782 { "lightSquareColor", "lightSquareColor", XtRString,
\r
783 sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
\r
784 XtRString, LIGHT_SQUARE_COLOR },
\r
785 { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
\r
786 XtOffset(AppDataPtr, darkSquareColor), XtRString,
\r
787 DARK_SQUARE_COLOR },
\r
788 { "highlightSquareColor", "highlightSquareColor", XtRString,
\r
789 sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
\r
790 XtRString, HIGHLIGHT_SQUARE_COLOR },
\r
791 { "premoveHighlightColor", "premoveHighlightColor", XtRString,
\r
792 sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
\r
793 XtRString, PREMOVE_HIGHLIGHT_COLOR },
\r
794 { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
\r
795 XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
\r
796 (XtPointer) MOVES_PER_SESSION },
\r
797 { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
\r
798 XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
\r
799 (XtPointer) TIME_INCREMENT },
\r
800 { "initString", "initString", XtRString, sizeof(String),
\r
801 XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
\r
802 { "secondInitString", "secondInitString", XtRString, sizeof(String),
\r
803 XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
\r
804 { "firstComputerString", "firstComputerString", XtRString,
\r
805 sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
\r
807 { "secondComputerString", "secondComputerString", XtRString,
\r
808 sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
\r
810 { "firstChessProgram", "firstChessProgram", XtRString,
\r
811 sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
\r
812 XtRString, FIRST_CHESS_PROGRAM },
\r
813 { "secondChessProgram", "secondChessProgram", XtRString,
\r
814 sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
\r
815 XtRString, SECOND_CHESS_PROGRAM },
\r
816 { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
\r
817 sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
\r
818 XtRImmediate, (XtPointer) False },
\r
819 { "noChessProgram", "noChessProgram", XtRBoolean,
\r
820 sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
\r
821 XtRImmediate, (XtPointer) False },
\r
822 { "firstHost", "firstHost", XtRString, sizeof(String),
\r
823 XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
\r
824 { "secondHost", "secondHost", XtRString, sizeof(String),
\r
825 XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
\r
826 { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
\r
827 XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
\r
828 { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
\r
829 XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
\r
830 { "bitmapDirectory", "bitmapDirectory", XtRString,
\r
831 sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
\r
833 { "remoteShell", "remoteShell", XtRString, sizeof(String),
\r
834 XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
\r
835 { "remoteUser", "remoteUser", XtRString, sizeof(String),
\r
836 XtOffset(AppDataPtr, remoteUser), XtRString, "" },
\r
837 { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
\r
838 XtOffset(AppDataPtr, timeDelay), XtRString,
\r
839 (XtPointer) TIME_DELAY_QUOTE },
\r
840 { "timeControl", "timeControl", XtRString, sizeof(String),
\r
841 XtOffset(AppDataPtr, timeControl), XtRString,
\r
842 (XtPointer) TIME_CONTROL },
\r
843 { "internetChessServerMode", "internetChessServerMode",
\r
844 XtRBoolean, sizeof(Boolean),
\r
845 XtOffset(AppDataPtr, icsActive), XtRImmediate,
\r
846 (XtPointer) False },
\r
847 { "internetChessServerHost", "internetChessServerHost",
\r
848 XtRString, sizeof(String),
\r
849 XtOffset(AppDataPtr, icsHost),
\r
850 XtRString, (XtPointer) ICS_HOST },
\r
851 { "internetChessServerPort", "internetChessServerPort",
\r
852 XtRString, sizeof(String),
\r
853 XtOffset(AppDataPtr, icsPort), XtRString,
\r
854 (XtPointer) ICS_PORT },
\r
855 { "internetChessServerCommPort", "internetChessServerCommPort",
\r
856 XtRString, sizeof(String),
\r
857 XtOffset(AppDataPtr, icsCommPort), XtRString,
\r
859 { "internetChessServerLogonScript", "internetChessServerLogonScript",
\r
860 XtRString, sizeof(String),
\r
861 XtOffset(AppDataPtr, icsLogon), XtRString,
\r
863 { "internetChessServerHelper", "internetChessServerHelper",
\r
864 XtRString, sizeof(String),
\r
865 XtOffset(AppDataPtr, icsHelper), XtRString, "" },
\r
866 { "internetChessServerInputBox", "internetChessServerInputBox",
\r
867 XtRBoolean, sizeof(Boolean),
\r
868 XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
\r
869 (XtPointer) False },
\r
870 { "icsAlarm", "icsAlarm",
\r
871 XtRBoolean, sizeof(Boolean),
\r
872 XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
\r
873 (XtPointer) True },
\r
874 { "icsAlarmTime", "icsAlarmTime",
\r
875 XtRInt, sizeof(int),
\r
876 XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
\r
877 (XtPointer) 5000 },
\r
878 { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
\r
879 XtOffset(AppDataPtr, useTelnet), XtRImmediate,
\r
880 (XtPointer) False },
\r
881 { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
\r
882 XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
\r
883 { "gateway", "gateway", XtRString, sizeof(String),
\r
884 XtOffset(AppDataPtr, gateway), XtRString, "" },
\r
885 { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
\r
886 XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
\r
887 { "loadGameIndex", "loadGameIndex",
\r
888 XtRInt, sizeof(int),
\r
889 XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
\r
891 { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
\r
892 XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
\r
893 { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
\r
894 sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
\r
895 XtRImmediate, (XtPointer) True },
\r
896 { "autoSaveGames", "autoSaveGames", XtRBoolean,
\r
897 sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
\r
898 XtRImmediate, (XtPointer) False },
\r
899 { "blindfold", "blindfold", XtRBoolean,
\r
900 sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
\r
901 XtRImmediate, (XtPointer) False },
\r
902 { "loadPositionFile", "loadPositionFile", XtRString,
\r
903 sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
\r
905 { "loadPositionIndex", "loadPositionIndex",
\r
906 XtRInt, sizeof(int),
\r
907 XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
\r
909 { "savePositionFile", "savePositionFile", XtRString,
\r
910 sizeof(String), XtOffset(AppDataPtr, savePositionFile),
\r
912 { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
\r
913 XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
\r
914 { "matchGames", "matchGames", XtRInt, sizeof(int),
\r
915 XtOffset(AppDataPtr, matchGames), XtRImmediate,
\r
917 { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
\r
918 XtOffset(AppDataPtr, monoMode), XtRImmediate,
\r
919 (XtPointer) False },
\r
920 { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
\r
921 XtOffset(AppDataPtr, debugMode), XtRImmediate,
\r
922 (XtPointer) False },
\r
923 { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
\r
924 XtOffset(AppDataPtr, clockMode), XtRImmediate,
\r
925 (XtPointer) True },
\r
926 { "boardSize", "boardSize", XtRString, sizeof(String),
\r
927 XtOffset(AppDataPtr, boardSize), XtRString, "" },
\r
928 { "searchTime", "searchTime", XtRString, sizeof(String),
\r
929 XtOffset(AppDataPtr, searchTime), XtRString,
\r
931 { "searchDepth", "searchDepth", XtRInt, sizeof(int),
\r
932 XtOffset(AppDataPtr, searchDepth), XtRImmediate,
\r
934 { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
\r
935 XtOffset(AppDataPtr, showCoords), XtRImmediate,
\r
936 (XtPointer) False },
\r
937 { "showJail", "showJail", XtRInt, sizeof(int),
\r
938 XtOffset(AppDataPtr, showJail), XtRImmediate,
\r
940 { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
\r
941 XtOffset(AppDataPtr, showThinking), XtRImmediate,
\r
942 (XtPointer) True },
\r
943 { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
\r
944 XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
\r
945 (XtPointer) True },
\r
946 { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
\r
947 XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
\r
948 (XtPointer) True },
\r
949 { "clockFont", "clockFont", XtRString, sizeof(String),
\r
950 XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
\r
951 { "coordFont", "coordFont", XtRString, sizeof(String),
\r
952 XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
\r
953 { "font", "font", XtRString, sizeof(String),
\r
954 XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
\r
955 { "ringBellAfterMoves", "ringBellAfterMoves",
\r
956 XtRBoolean, sizeof(Boolean),
\r
957 XtOffset(AppDataPtr, ringBellAfterMoves),
\r
958 XtRImmediate, (XtPointer) False },
\r
959 { "autoCallFlag", "autoCallFlag", XtRBoolean,
\r
960 sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
\r
961 XtRImmediate, (XtPointer) False },
\r
962 { "autoFlipView", "autoFlipView", XtRBoolean,
\r
963 sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
\r
964 XtRImmediate, (XtPointer) True },
\r
965 { "autoObserve", "autoObserve", XtRBoolean,
\r
966 sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
\r
967 XtRImmediate, (XtPointer) False },
\r
968 { "autoComment", "autoComment", XtRBoolean,
\r
969 sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
\r
970 XtRImmediate, (XtPointer) False },
\r
971 { "getMoveList", "getMoveList", XtRBoolean,
\r
972 sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
\r
973 XtRImmediate, (XtPointer) True },
\r
975 { "highlightDragging", "highlightDragging", XtRBoolean,
\r
976 sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
\r
977 XtRImmediate, (XtPointer) False },
\r
979 { "highlightLastMove", "highlightLastMove", XtRBoolean,
\r
980 sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
\r
981 XtRImmediate, (XtPointer) False },
\r
982 { "premove", "premove", XtRBoolean,
\r
983 sizeof(Boolean), XtOffset(AppDataPtr, premove),
\r
984 XtRImmediate, (XtPointer) True },
\r
985 { "testLegality", "testLegality", XtRBoolean,
\r
986 sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
\r
987 XtRImmediate, (XtPointer) True },
\r
988 { "flipView", "flipView", XtRBoolean,
\r
989 sizeof(Boolean), XtOffset(AppDataPtr, flipView),
\r
990 XtRImmediate, (XtPointer) False },
\r
991 { "cmail", "cmailGameName", XtRString, sizeof(String),
\r
992 XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
\r
993 { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
\r
994 sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
\r
995 XtRImmediate, (XtPointer) False },
\r
996 { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
\r
997 sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
\r
998 XtRImmediate, (XtPointer) False },
\r
999 { "quietPlay", "quietPlay", XtRBoolean,
\r
1000 sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
\r
1001 XtRImmediate, (XtPointer) False },
\r
1002 { "titleInWindow", "titleInWindow", XtRBoolean,
\r
1003 sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
\r
1004 XtRImmediate, (XtPointer) False },
\r
1005 { "localLineEditing", "localLineEditing", XtRBoolean,
\r
1006 sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
\r
1007 XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
\r
1009 { "zippyTalk", "zippyTalk", XtRBoolean,
\r
1010 sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
\r
1011 XtRImmediate, (XtPointer) ZIPPY_TALK },
\r
1012 { "zippyPlay", "zippyPlay", XtRBoolean,
\r
1013 sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
\r
1014 XtRImmediate, (XtPointer) ZIPPY_PLAY },
\r
1015 { "zippyLines", "zippyLines", XtRString, sizeof(String),
\r
1016 XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
\r
1017 { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
\r
1018 XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
\r
1019 { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
\r
1020 XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
\r
1021 { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
\r
1022 XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
\r
1023 { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
\r
1024 XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
\r
1025 ZIPPY_WRONG_PASSWORD },
\r
1026 { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
\r
1027 XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
\r
1028 { "zippyUseI", "zippyUseI", XtRBoolean,
\r
1029 sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
\r
1030 XtRImmediate, (XtPointer) ZIPPY_USE_I },
\r
1031 { "zippyBughouse", "zippyBughouse", XtRInt,
\r
1032 sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
\r
1033 XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
\r
1034 { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
\r
1035 sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
\r
1036 XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
\r
1037 { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
\r
1038 XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
\r
1039 { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
\r
1040 XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
\r
1041 { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
\r
1042 sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
\r
1043 XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
\r
1044 { "zippyAbort", "zippyAbort", XtRBoolean,
\r
1045 sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
\r
1046 XtRImmediate, (XtPointer) ZIPPY_ABORT },
\r
1047 { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
\r
1048 XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
\r
1049 { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
\r
1050 XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
\r
1051 (XtPointer) ZIPPY_MAX_GAMES },
\r
1052 { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
\r
1053 XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
\r
1054 (XtPointer) ZIPPY_REPLAY_TIMEOUT },
\r
1056 { "flashCount", "flashCount", XtRInt, sizeof(int),
\r
1057 XtOffset(AppDataPtr, flashCount), XtRImmediate,
\r
1058 (XtPointer) FLASH_COUNT },
\r
1059 { "flashRate", "flashRate", XtRInt, sizeof(int),
\r
1060 XtOffset(AppDataPtr, flashRate), XtRImmediate,
\r
1061 (XtPointer) FLASH_RATE },
\r
1062 { "pixmapDirectory", "pixmapDirectory", XtRString,
\r
1063 sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
\r
1065 { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
\r
1066 XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
\r
1067 (XtPointer) MS_LOGIN_DELAY },
\r
1068 { "colorizeMessages", "colorizeMessages", XtRBoolean,
\r
1069 sizeof(Boolean), XtOffset(AppDataPtr, colorize),
\r
1070 XtRImmediate, (XtPointer) False },
\r
1071 { "colorShout", "colorShout", XtRString,
\r
1072 sizeof(String), XtOffset(AppDataPtr, colorShout),
\r
1073 XtRString, COLOR_SHOUT },
\r
1074 { "colorSShout", "colorSShout", XtRString,
\r
1075 sizeof(String), XtOffset(AppDataPtr, colorSShout),
\r
1076 XtRString, COLOR_SSHOUT },
\r
1077 { "colorChannel1", "colorChannel1", XtRString,
\r
1078 sizeof(String), XtOffset(AppDataPtr, colorChannel1),
\r
1079 XtRString, COLOR_CHANNEL1 },
\r
1080 { "colorChannel", "colorChannel", XtRString,
\r
1081 sizeof(String), XtOffset(AppDataPtr, colorChannel),
\r
1082 XtRString, COLOR_CHANNEL },
\r
1083 { "colorKibitz", "colorKibitz", XtRString,
\r
1084 sizeof(String), XtOffset(AppDataPtr, colorKibitz),
\r
1085 XtRString, COLOR_KIBITZ },
\r
1086 { "colorTell", "colorTell", XtRString,
\r
1087 sizeof(String), XtOffset(AppDataPtr, colorTell),
\r
1088 XtRString, COLOR_TELL },
\r
1089 { "colorChallenge", "colorChallenge", XtRString,
\r
1090 sizeof(String), XtOffset(AppDataPtr, colorChallenge),
\r
1091 XtRString, COLOR_CHALLENGE },
\r
1092 { "colorRequest", "colorRequest", XtRString,
\r
1093 sizeof(String), XtOffset(AppDataPtr, colorRequest),
\r
1094 XtRString, COLOR_REQUEST },
\r
1095 { "colorSeek", "colorSeek", XtRString,
\r
1096 sizeof(String), XtOffset(AppDataPtr, colorSeek),
\r
1097 XtRString, COLOR_SEEK },
\r
1098 { "colorNormal", "colorNormal", XtRString,
\r
1099 sizeof(String), XtOffset(AppDataPtr, colorNormal),
\r
1100 XtRString, COLOR_NORMAL },
\r
1101 { "soundProgram", "soundProgram", XtRString,
\r
1102 sizeof(String), XtOffset(AppDataPtr, soundProgram),
\r
1103 XtRString, "play" },
\r
1104 { "soundShout", "soundShout", XtRString,
\r
1105 sizeof(String), XtOffset(AppDataPtr, soundShout),
\r
1107 { "soundSShout", "soundSShout", XtRString,
\r
1108 sizeof(String), XtOffset(AppDataPtr, soundSShout),
\r
1110 { "soundChannel1", "soundChannel1", XtRString,
\r
1111 sizeof(String), XtOffset(AppDataPtr, soundChannel1),
\r
1113 { "soundChannel", "soundChannel", XtRString,
\r
1114 sizeof(String), XtOffset(AppDataPtr, soundChannel),
\r
1116 { "soundKibitz", "soundKibitz", XtRString,
\r
1117 sizeof(String), XtOffset(AppDataPtr, soundKibitz),
\r
1119 { "soundTell", "soundTell", XtRString,
\r
1120 sizeof(String), XtOffset(AppDataPtr, soundTell),
\r
1122 { "soundChallenge", "soundChallenge", XtRString,
\r
1123 sizeof(String), XtOffset(AppDataPtr, soundChallenge),
\r
1125 { "soundRequest", "soundRequest", XtRString,
\r
1126 sizeof(String), XtOffset(AppDataPtr, soundRequest),
\r
1128 { "soundSeek", "soundSeek", XtRString,
\r
1129 sizeof(String), XtOffset(AppDataPtr, soundSeek),
\r
1131 { "soundMove", "soundMove", XtRString,
\r
1132 sizeof(String), XtOffset(AppDataPtr, soundMove),
\r
1134 { "soundIcsWin", "soundIcsWin", XtRString,
\r
1135 sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
\r
1137 { "soundIcsLoss", "soundIcsLoss", XtRString,
\r
1138 sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
\r
1140 { "soundIcsDraw", "soundIcsDraw", XtRString,
\r
1141 sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
\r
1143 { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
\r
1144 sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
\r
1146 { "soundIcsAlarm", "soundIcsAlarm", XtRString,
\r
1147 sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
\r
1149 { "reuseFirst", "reuseFirst", XtRBoolean,
\r
1150 sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
\r
1151 XtRImmediate, (XtPointer) True },
\r
1152 { "reuseSecond", "reuseSecond", XtRBoolean,
\r
1153 sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
\r
1154 XtRImmediate, (XtPointer) True },
\r
1155 { "animateDragging", "animateDragging", XtRBoolean,
\r
1156 sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
\r
1157 XtRImmediate, (XtPointer) True },
\r
1158 { "animateMoving", "animateMoving", XtRBoolean,
\r
1159 sizeof(Boolean), XtOffset(AppDataPtr, animate),
\r
1160 XtRImmediate, (XtPointer) True },
\r
1161 { "animateSpeed", "animateSpeed", XtRInt,
\r
1162 sizeof(int), XtOffset(AppDataPtr, animSpeed),
\r
1163 XtRImmediate, (XtPointer)10 },
\r
1164 { "popupExitMessage", "popupExitMessage", XtRBoolean,
\r
1165 sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
\r
1166 XtRImmediate, (XtPointer) True },
\r
1167 { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
\r
1168 sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
\r
1169 XtRImmediate, (XtPointer) False },
\r
1170 { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
\r
1171 sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
\r
1172 XtRImmediate, (XtPointer)4 },
\r
1173 { "initialMode", "initialMode", XtRString,
\r
1174 sizeof(String), XtOffset(AppDataPtr, initialMode),
\r
1175 XtRImmediate, (XtPointer) "" },
\r
1176 { "variant", "variant", XtRString,
\r
1177 sizeof(String), XtOffset(AppDataPtr, variant),
\r
1178 XtRImmediate, (XtPointer) "normal" },
\r
1179 { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
\r
1180 sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
\r
1181 XtRImmediate, (XtPointer)PROTOVER },
\r
1182 { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
\r
1183 sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
\r
1184 XtRImmediate, (XtPointer)PROTOVER },
\r
1185 { "showButtonBar", "showButtonBar", XtRBoolean,
\r
1186 sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
\r
1187 XtRImmediate, (XtPointer) True },
\r
1188 {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean, /* [DM] icsEngineAnalyze */
\r
1189 sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
\r
1190 XtRImmediate, (XtPointer) False },
\r
1191 { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
\r
1192 sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
\r
1193 XtRImmediate, (XtPointer) False },
\r
1194 { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
\r
1195 sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
\r
1196 XtRImmediate, (XtPointer) False },
\r
1197 { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
\r
1198 sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
\r
1199 XtRImmediate, (XtPointer) False },
\r
1200 { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
\r
1201 sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
\r
1202 XtRImmediate, (XtPointer) True },
\r
1203 { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
\r
1204 sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
\r
1205 XtRImmediate, (XtPointer) 0},
\r
1206 { "pgnEventHeader", "pgnEventHeader", XtRString,
\r
1207 sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
\r
1208 XtRImmediate, (XtPointer) "Computer Chess Game" },
\r
1209 { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
\r
1210 sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
\r
1211 XtRImmediate, (XtPointer) -1},
\r
1213 // [HGM] 4.3.xx options
\r
1214 { "boardWidth", "boardWidth", XtRInt,
\r
1215 sizeof(int), XtOffset(AppDataPtr, NrFiles),
\r
1216 XtRImmediate, (XtPointer) -1},
\r
1217 { "boardHeight", "boardHeight", XtRInt,
\r
1218 sizeof(int), XtOffset(AppDataPtr, NrRanks),
\r
1219 XtRImmediate, (XtPointer) -1},
\r
1220 { "matchPause", "matchPause", XtRInt,
\r
1221 sizeof(int), XtOffset(AppDataPtr, matchPause),
\r
1222 XtRImmediate, (XtPointer) 10000},
\r
1223 { "holdingsSize", "holdingsSize", XtRInt,
\r
1224 sizeof(int), XtOffset(AppDataPtr, holdingsSize),
\r
1225 XtRImmediate, (XtPointer) -1},
\r
1226 { "flipBlack", "flipBlack", XtRBoolean,
\r
1227 sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
\r
1228 XtRImmediate, (XtPointer) False},
\r
1229 { "allWhite", "allWhite", XtRBoolean,
\r
1230 sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
\r
1231 XtRImmediate, (XtPointer) False},
\r
1232 { "pieceToCharTable", "pieceToCharTable", XtRString,
\r
1233 sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
\r
1234 XtRImmediate, (XtPointer) 0},
\r
1235 { "alphaRank", "alphaRank", XtRBoolean,
\r
1236 sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
\r
1237 XtRImmediate, (XtPointer) False},
\r
1238 { "testClaims", "testClaims", XtRBoolean,
\r
1239 sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
\r
1240 XtRImmediate, (XtPointer) True},
\r
1241 { "checkMates", "checkMates", XtRBoolean,
\r
1242 sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
\r
1243 XtRImmediate, (XtPointer) True},
\r
1244 { "materialDraws", "materialDraws", XtRBoolean,
\r
1245 sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
\r
1246 XtRImmediate, (XtPointer) True},
\r
1247 { "trivialDraws", "trivialDraws", XtRBoolean,
\r
1248 sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
\r
1249 XtRImmediate, (XtPointer) False},
\r
1250 { "ruleMoves", "ruleMoves", XtRInt,
\r
1251 sizeof(int), XtOffset(AppDataPtr, ruleMoves),
\r
1252 XtRImmediate, (XtPointer) 51},
\r
1253 { "repeatsToDraw", "repeatsToDraw", XtRInt,
\r
1254 sizeof(int), XtOffset(AppDataPtr, drawRepeats),
\r
1255 XtRImmediate, (XtPointer) 6},
\r
1256 { "engineDebugOutput", "engineDebugOutput", XtRInt,
\r
1257 sizeof(int), XtOffset(AppDataPtr, engineComments),
\r
1258 XtRImmediate, (XtPointer) 1},
\r
1259 { "userName", "userName", XtRString,
\r
1260 sizeof(int), XtOffset(AppDataPtr, userName),
\r
1261 XtRImmediate, (XtPointer) 0},
\r
1262 { "autoKibitz", "autoKibitz", XtRBoolean,
\r
1263 sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
\r
1264 XtRImmediate, (XtPointer) False},
\r
1265 { "firstTimeOdds", "firstTimeOdds", XtRInt,
\r
1266 sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
\r
1267 XtRImmediate, (XtPointer) 1},
\r
1268 { "secondTimeOdds", "secondTimeOdds", XtRInt,
\r
1269 sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
\r
1270 XtRImmediate, (XtPointer) 1},
\r
1271 { "timeOddsMode", "timeOddsMode", XtRInt,
\r
1272 sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
\r
1273 XtRImmediate, (XtPointer) 0},
\r
1274 { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
\r
1275 sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
\r
1276 XtRImmediate, (XtPointer) 1},
\r
1277 { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
\r
1278 sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
\r
1279 XtRImmediate, (XtPointer) 1},
\r
1280 { "firstNPS", "firstNPS", XtRInt,
\r
1281 sizeof(int), XtOffset(AppDataPtr, firstNPS),
\r
1282 XtRImmediate, (XtPointer) -1},
\r
1283 { "secondNPS", "secondNPS", XtRInt,
\r
1284 sizeof(int), XtOffset(AppDataPtr, secondNPS),
\r
1285 XtRImmediate, (XtPointer) -1},
\r
1286 { "serverMoves", "serverMoves", XtRString,
\r
1287 sizeof(String), XtOffset(AppDataPtr, serverMovesName),
\r
1288 XtRImmediate, (XtPointer) 0},
\r
1289 { "serverPause", "serverPause", XtRInt,
\r
1290 sizeof(int), XtOffset(AppDataPtr, serverPause),
\r
1291 XtRImmediate, (XtPointer) 0},
\r
1292 { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
\r
1293 sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
\r
1294 XtRImmediate, (XtPointer) False},
\r
1295 { "userName", "userName", XtRString,
\r
1296 sizeof(String), XtOffset(AppDataPtr, userName),
\r
1297 XtRImmediate, (XtPointer) 0},
\r
1298 { "egtFormats", "egtFormats", XtRString,
\r
1299 sizeof(String), XtOffset(AppDataPtr, egtFormats),
\r
1300 XtRImmediate, (XtPointer) 0},
\r
1301 { "rewindIndex", "rewindIndex", XtRInt,
\r
1302 sizeof(int), XtOffset(AppDataPtr, rewindIndex),
\r
1303 XtRImmediate, (XtPointer) 0},
\r
1304 { "sameColorGames", "sameColorGames", XtRInt,
\r
1305 sizeof(int), XtOffset(AppDataPtr, sameColorGames),
\r
1306 XtRImmediate, (XtPointer) 0},
\r
1307 { "smpCores", "smpCores", XtRInt,
\r
1308 sizeof(int), XtOffset(AppDataPtr, smpCores),
\r
1309 XtRImmediate, (XtPointer) 1},
\r
1310 { "niceEngines", "niceEngines", XtRInt,
\r
1311 sizeof(int), XtOffset(AppDataPtr, niceEngines),
\r
1312 XtRImmediate, (XtPointer) 0},
\r
1313 { "nameOfDebugFile", "nameOfDebugFile", XtRString,
\r
1314 sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
\r
1315 XtRImmediate, (XtPointer) "xboard.debug"},
\r
1316 { "noGUI", "noGUI", XtRBoolean,
\r
1317 sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
\r
1318 XtRImmediate, (XtPointer) 0},
\r
1319 { "firstOptions", "firstOptions", XtRString,
\r
1320 sizeof(String), XtOffset(AppDataPtr, firstOptions),
\r
1321 XtRImmediate, (XtPointer) "" },
\r
1322 { "secondOptions", "secondOptions", XtRString,
\r
1323 sizeof(String), XtOffset(AppDataPtr, secondOptions),
\r
1324 XtRImmediate, (XtPointer) "" },
\r
1326 // [HGM] Winboard_x UCI options
\r
1327 { "firstIsUCI", "firstIsUCI", XtRBoolean,
\r
1328 sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
\r
1329 XtRImmediate, (XtPointer) False},
\r
1330 { "secondIsUCI", "secondIsUCI", XtRBoolean,
\r
1331 sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
\r
1332 XtRImmediate, (XtPointer) False},
\r
1333 { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
\r
1334 sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
\r
1335 XtRImmediate, (XtPointer) True},
\r
1336 { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
\r
1337 sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
\r
1338 XtRImmediate, (XtPointer) True},
\r
1339 { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
\r
1340 sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
\r
1341 XtRImmediate, (XtPointer) False},
\r
1342 { "defaultHashSize", "defaultHashSize", XtRInt,
\r
1343 sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
\r
1344 XtRImmediate, (XtPointer) 64},
\r
1345 { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
\r
1346 sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
\r
1347 XtRImmediate, (XtPointer) 4},
\r
1348 { "polyglotDir", "polyglotDir", XtRString,
\r
1349 sizeof(String), XtOffset(AppDataPtr, polyglotDir),
\r
1350 XtRImmediate, (XtPointer) "." },
\r
1351 { "polyglotBook", "polyglotBook", XtRString,
\r
1352 sizeof(String), XtOffset(AppDataPtr, polyglotBook),
\r
1353 XtRImmediate, (XtPointer) "" },
\r
1354 { "defaultPathEGTB", "defaultPathEGTB", XtRString,
\r
1355 sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
\r
1356 XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
\r
1357 { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
\r
1358 sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
\r
1359 XtRImmediate, (XtPointer) 0},
\r
1360 { "delayAfterQuit", "delayAfterQuit", XtRInt,
\r
1361 sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
\r
1362 XtRImmediate, (XtPointer) 0},
\r
1365 XrmOptionDescRec shellOptions[] = {
\r
1366 { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
\r
1367 { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
\r
1368 { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
\r
1369 { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
\r
1370 { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
\r
1371 { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
\r
1372 { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
\r
1373 { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
\r
1374 { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
\r
1375 { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
\r
1376 { "-initString", "initString", XrmoptionSepArg, NULL },
\r
1377 { "-firstInitString", "initString", XrmoptionSepArg, NULL },
\r
1378 { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
\r
1379 { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
\r
1380 { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
\r
1381 { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
\r
1382 { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
\r
1383 { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
\r
1384 { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
\r
1385 { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
\r
1386 { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
\r
1387 { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
\r
1388 { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
\r
1389 { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
\r
1390 { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
\r
1391 { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
\r
1392 { "-fh", "firstHost", XrmoptionSepArg, NULL },
\r
1393 { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
\r
1394 { "-sh", "secondHost", XrmoptionSepArg, NULL },
\r
1395 { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
\r
1396 { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
\r
1397 { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
\r
1398 { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
\r
1399 { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
\r
1400 { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
\r
1401 { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
\r
1402 { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
\r
1403 { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
\r
1404 { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
\r
1405 { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
\r
1406 { "-td", "timeDelay", XrmoptionSepArg, NULL },
\r
1407 { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
\r
1408 { "-tc", "timeControl", XrmoptionSepArg, NULL },
\r
1409 { "-internetChessServerMode", "internetChessServerMode",
\r
1410 XrmoptionSepArg, NULL },
\r
1411 { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
\r
1412 { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
\r
1413 { "-internetChessServerHost", "internetChessServerHost",
\r
1414 XrmoptionSepArg, NULL },
\r
1415 { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
\r
1416 { "-internetChessServerPort", "internetChessServerPort",
\r
1417 XrmoptionSepArg, NULL },
\r
1418 { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
\r
1419 { "-internetChessServerCommPort", "internetChessServerCommPort",
\r
1420 XrmoptionSepArg, NULL },
\r
1421 { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
\r
1422 { "-internetChessServerLogonScript", "internetChessServerLogonScript",
\r
1423 XrmoptionSepArg, NULL },
\r
1424 { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
\r
1425 { "-internetChessServerHelper", "internetChessServerHelper",
\r
1426 XrmoptionSepArg, NULL },
\r
1427 { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
\r
1428 { "-internetChessServerInputBox", "internetChessServerInputBox",
\r
1429 XrmoptionSepArg, NULL },
\r
1430 { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
\r
1431 { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
\r
1432 { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
\r
1433 { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
\r
1434 { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
\r
1435 { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
\r
1436 { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
\r
1437 { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
\r
1438 { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
\r
1439 { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
\r
1440 { "-gateway", "gateway", XrmoptionSepArg, NULL },
\r
1441 { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
\r
1442 { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
\r
1443 { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
\r
1444 { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
\r
1445 { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
\r
1446 { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
\r
1447 { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
\r
1448 { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
\r
1449 { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
\r
1450 { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
\r
1451 { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
\r
1452 { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
\r
1453 { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
\r
1454 { "-blind", "blindfold", XrmoptionNoArg, "True" },
\r
1455 { "-xblind", "blindfold", XrmoptionNoArg, "False" },
\r
1456 { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
\r
1457 { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
\r
1458 { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
\r
1459 { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
\r
1460 { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
\r
1461 { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
\r
1462 { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
\r
1463 { "-mm", "matchMode", XrmoptionNoArg, "True" },
\r
1464 { "-xmm", "matchMode", XrmoptionNoArg, "False" },
\r
1465 { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
\r
1466 { "-mg", "matchGames", XrmoptionSepArg, NULL },
\r
1467 { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
\r
1468 { "-mono", "monoMode", XrmoptionNoArg, "True" },
\r
1469 { "-xmono", "monoMode", XrmoptionNoArg, "False" },
\r
1470 { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
\r
1471 { "-debug", "debugMode", XrmoptionNoArg, "True" },
\r
1472 { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
\r
1473 { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
\r
1474 { "-clock", "clockMode", XrmoptionNoArg, "True" },
\r
1475 { "-xclock", "clockMode", XrmoptionNoArg, "False" },
\r
1476 { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
\r
1477 { "-size", "boardSize", XrmoptionSepArg, NULL },
\r
1478 { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
\r
1479 { "-st", "searchTime", XrmoptionSepArg, NULL },
\r
1480 { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
\r
1481 { "-depth", "searchDepth", XrmoptionSepArg, NULL },
\r
1482 { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
\r
1483 { "-coords", "showCoords", XrmoptionNoArg, "True" },
\r
1484 { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
\r
1486 { "-showJail", "showJail", XrmoptionSepArg, NULL },
\r
1487 { "-jail", "showJail", XrmoptionNoArg, "1" },
\r
1488 { "-sidejail", "showJail", XrmoptionNoArg, "2" },
\r
1489 { "-xjail", "showJail", XrmoptionNoArg, "0" },
\r
1491 { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
\r
1492 { "-thinking", "showThinking", XrmoptionNoArg, "True" },
\r
1493 { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
\r
1494 { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
\r
1495 { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
\r
1496 { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
\r
1497 { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
\r
1498 { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
\r
1499 { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
\r
1500 { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
\r
1501 { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
\r
1502 { "-font", "font", XrmoptionSepArg, NULL },
\r
1503 { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
\r
1504 { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
\r
1505 { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
\r
1506 { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
\r
1507 { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
\r
1508 { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
\r
1509 { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
\r
1510 { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
\r
1511 { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
\r
1512 { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
\r
1513 { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
\r
1514 { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
\r
1515 { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
\r
1516 { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
\r
1517 { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
\r
1518 { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
\r
1519 { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
\r
1520 { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
\r
1521 { "-moves", "getMoveList", XrmoptionNoArg, "True" },
\r
1522 { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
\r
1524 { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
\r
1525 { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
\r
1526 { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
\r
1528 { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
\r
1529 { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
\r
1530 { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
\r
1531 { "-premove", "premove", XrmoptionSepArg, NULL },
\r
1532 { "-pre", "premove", XrmoptionNoArg, "True" },
\r
1533 { "-xpre", "premove", XrmoptionNoArg, "False" },
\r
1534 { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
\r
1535 { "-legal", "testLegality", XrmoptionNoArg, "True" },
\r
1536 { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
\r
1537 { "-flipView", "flipView", XrmoptionSepArg, NULL },
\r
1538 { "-flip", "flipView", XrmoptionNoArg, "True" },
\r
1539 { "-xflip", "flipView", XrmoptionNoArg, "False" },
\r
1540 { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
\r
1541 { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
\r
1542 XrmoptionSepArg, NULL },
\r
1543 { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
\r
1544 { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
\r
1545 { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
\r
1546 { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
\r
1547 { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
\r
1548 { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
\r
1549 { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
\r
1550 { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
\r
1551 { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
\r
1552 { "-title", "titleInWindow", XrmoptionNoArg, "True" },
\r
1553 { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
\r
1555 { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
\r
1556 { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
\r
1557 { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
\r
1558 { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
\r
1559 { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
\r
1560 { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
\r
1561 { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
\r
1562 { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
\r
1563 { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
\r
1564 { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
\r
1565 { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
\r
1566 { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
\r
1567 { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
\r
1568 { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
\r
1569 { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
\r
1570 { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
\r
1571 { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
\r
1572 { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
\r
1573 { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
\r
1574 { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
\r
1575 { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
\r
1576 { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
\r
1577 { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
\r
1578 { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
\r
1579 { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
\r
1580 { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
\r
1581 { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
\r
1582 { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
\r
1583 { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
\r
1584 { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
\r
1586 { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
\r
1587 { "-flash", "flashCount", XrmoptionNoArg, "3" },
\r
1588 { "-xflash", "flashCount", XrmoptionNoArg, "0" },
\r
1589 { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
\r
1590 { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
\r
1591 { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
\r
1592 { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
\r
1593 { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
\r
1594 { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
\r
1595 { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
\r
1596 { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
\r
1597 { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
\r
1598 { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
\r
1599 { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
\r
1600 { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
\r
1601 { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
\r
1602 { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
\r
1603 { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
\r
1604 { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
\r
1605 { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
\r
1606 { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
\r
1607 { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
\r
1608 { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
\r
1609 { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
\r
1610 { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
\r
1611 { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
\r
1612 { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
\r
1613 { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
\r
1614 { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
\r
1615 { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
\r
1616 { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
\r
1617 { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
\r
1618 { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
\r
1619 { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
\r
1620 { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
\r
1621 { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
\r
1622 { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
\r
1623 { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
\r
1624 { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
\r
1625 { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
\r
1626 { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
\r
1627 { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
\r
1628 { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
\r
1629 { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
\r
1630 { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
\r
1631 { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
\r
1632 { "-animate", "animateMoving", XrmoptionNoArg, "True" },
\r
1633 { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
\r
1634 { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
\r
1635 { "-drag", "animateDragging", XrmoptionNoArg, "True" },
\r
1636 { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
\r
1637 { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
\r
1638 { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
\r
1639 { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
\r
1640 { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
\r
1641 { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
\r
1642 { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
\r
1643 { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
\r
1644 { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
\r
1645 { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
\r
1646 { "-mode", "initialMode", XrmoptionSepArg, NULL },
\r
1647 { "-variant", "variant", XrmoptionSepArg, NULL },
\r
1648 { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
\r
1649 { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
\r
1650 { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
\r
1651 { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
\r
1652 { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
\r
1653 /* [AS,HR] New features */
\r
1654 { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
\r
1655 { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
\r
1656 { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
\r
1657 { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
\r
1658 { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
\r
1659 { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
\r
1660 { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
\r
1661 { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
\r
1662 { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
\r
1663 { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
\r
1664 { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
\r
1665 { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
\r
1666 { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1667 { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1668 { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1669 { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1670 { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
\r
1671 { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
\r
1672 { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
\r
1673 { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
\r
1674 { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
\r
1675 { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
\r
1676 { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
\r
1677 // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
\r
1679 /* [HGM,HR] User-selectable board size */
\r
1680 { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
\r
1681 { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
\r
1682 { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
\r
1684 /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
\r
1685 { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
\r
1686 { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL }, // requires front-end changes to work
\r
1687 { "-allWhite", "allWhite", XrmoptionSepArg, NULL }, // requires front-end changes to work
\r
1688 { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
\r
1689 { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
\r
1690 { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
\r
1691 { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
\r
1692 { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
\r
1693 { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
\r
1694 { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
\r
1695 { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
\r
1696 { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
\r
1697 { "-userName", "userName", XrmoptionSepArg, NULL },
\r
1698 { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
\r
1699 { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
\r
1700 { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
\r
1701 { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
\r
1702 { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
\r
1703 { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
\r
1704 { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
\r
1705 { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
\r
1706 { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
\r
1707 { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
\r
1708 { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
\r
1709 { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
\r
1710 { "-userName", "userName", XrmoptionSepArg, NULL },
\r
1711 { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
\r
1712 { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
\r
1713 { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
\r
1714 { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
\r
1715 { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
\r
1716 { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
\r
1717 { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
\r
1718 { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
\r
1719 { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
\r
1720 { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
\r
1724 XtActionsRec boardActions[] = {
\r
1725 { "DrawPosition", DrawPositionProc },
\r
1726 { "HandleUserMove", HandleUserMove },
\r
1727 { "AnimateUserMove", AnimateUserMove },
\r
1728 { "FileNameAction", FileNameAction },
\r
1729 { "AskQuestionProc", AskQuestionProc },
\r
1730 { "AskQuestionReplyAction", AskQuestionReplyAction },
\r
1731 { "PieceMenuPopup", PieceMenuPopup },
\r
1732 { "WhiteClock", WhiteClock },
\r
1733 { "BlackClock", BlackClock },
\r
1734 { "Iconify", Iconify },
\r
1735 { "ResetProc", ResetProc },
\r
1736 { "LoadGameProc", LoadGameProc },
\r
1737 { "LoadNextGameProc", LoadNextGameProc },
\r
1738 { "LoadPrevGameProc", LoadPrevGameProc },
\r
1739 { "LoadSelectedProc", LoadSelectedProc },
\r
1740 { "ReloadGameProc", ReloadGameProc },
\r
1741 { "LoadPositionProc", LoadPositionProc },
\r
1742 { "LoadNextPositionProc", LoadNextPositionProc },
\r
1743 { "LoadPrevPositionProc", LoadPrevPositionProc },
\r
1744 { "ReloadPositionProc", ReloadPositionProc },
\r
1745 { "CopyPositionProc", CopyPositionProc },
\r
1746 { "PastePositionProc", PastePositionProc },
\r
1747 { "CopyGameProc", CopyGameProc },
\r
1748 { "PasteGameProc", PasteGameProc },
\r
1749 { "SaveGameProc", SaveGameProc },
\r
1750 { "SavePositionProc", SavePositionProc },
\r
1751 { "MailMoveProc", MailMoveProc },
\r
1752 { "ReloadCmailMsgProc", ReloadCmailMsgProc },
\r
1753 { "QuitProc", QuitProc },
\r
1754 { "MachineWhiteProc", MachineWhiteProc },
\r
1755 { "MachineBlackProc", MachineBlackProc },
\r
1756 { "AnalysisModeProc", AnalyzeModeProc },
\r
1757 { "AnalyzeFileProc", AnalyzeFileProc },
\r
1758 { "TwoMachinesProc", TwoMachinesProc },
\r
1759 { "IcsClientProc", IcsClientProc },
\r
1760 { "EditGameProc", EditGameProc },
\r
1761 { "EditPositionProc", EditPositionProc },
\r
1762 { "TrainingProc", EditPositionProc },
\r
1763 { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
\r
1764 { "ShowGameListProc", ShowGameListProc },
\r
1765 { "ShowMoveListProc", HistoryShowProc},
\r
1766 { "EditTagsProc", EditCommentProc },
\r
1767 { "EditCommentProc", EditCommentProc },
\r
1768 { "IcsAlarmProc", IcsAlarmProc },
\r
1769 { "IcsInputBoxProc", IcsInputBoxProc },
\r
1770 { "PauseProc", PauseProc },
\r
1771 { "AcceptProc", AcceptProc },
\r
1772 { "DeclineProc", DeclineProc },
\r
1773 { "RematchProc", RematchProc },
\r
1774 { "CallFlagProc", CallFlagProc },
\r
1775 { "DrawProc", DrawProc },
\r
1776 { "AdjournProc", AdjournProc },
\r
1777 { "AbortProc", AbortProc },
\r
1778 { "ResignProc", ResignProc },
\r
1779 { "EnterKeyProc", EnterKeyProc },
\r
1780 { "StopObservingProc", StopObservingProc },
\r
1781 { "StopExaminingProc", StopExaminingProc },
\r
1782 { "BackwardProc", BackwardProc },
\r
1783 { "ForwardProc", ForwardProc },
\r
1784 { "ToStartProc", ToStartProc },
\r
1785 { "ToEndProc", ToEndProc },
\r
1786 { "RevertProc", RevertProc },
\r
1787 { "TruncateGameProc", TruncateGameProc },
\r
1788 { "MoveNowProc", MoveNowProc },
\r
1789 { "RetractMoveProc", RetractMoveProc },
\r
1790 { "AlwaysQueenProc", AlwaysQueenProc },
\r
1791 { "AnimateDraggingProc", AnimateDraggingProc },
\r
1792 { "AnimateMovingProc", AnimateMovingProc },
\r
1793 { "AutoflagProc", AutoflagProc },
\r
1794 { "AutoflipProc", AutoflipProc },
\r
1795 { "AutobsProc", AutobsProc },
\r
1796 { "AutoraiseProc", AutoraiseProc },
\r
1797 { "AutosaveProc", AutosaveProc },
\r
1798 { "BlindfoldProc", BlindfoldProc },
\r
1799 { "FlashMovesProc", FlashMovesProc },
\r
1800 { "FlipViewProc", FlipViewProc },
\r
1801 { "GetMoveListProc", GetMoveListProc },
\r
1803 { "HighlightDraggingProc", HighlightDraggingProc },
\r
1805 { "HighlightLastMoveProc", HighlightLastMoveProc },
\r
1806 { "IcsAlarmProc", IcsAlarmProc },
\r
1807 { "MoveSoundProc", MoveSoundProc },
\r
1808 { "OldSaveStyleProc", OldSaveStyleProc },
\r
1809 { "PeriodicUpdatesProc", PeriodicUpdatesProc },
\r
1810 { "PonderNextMoveProc", PonderNextMoveProc },
\r
1811 { "PopupExitMessageProc", PopupExitMessageProc },
\r
1812 { "PopupMoveErrorsProc", PopupMoveErrorsProc },
\r
1813 { "PremoveProc", PremoveProc },
\r
1814 { "QuietPlayProc", QuietPlayProc },
\r
1815 { "ShowCoordsProc", ShowCoordsProc },
\r
1816 { "ShowThinkingProc", ShowThinkingProc },
\r
1817 { "HideThinkingProc", HideThinkingProc },
\r
1818 { "TestLegalityProc", TestLegalityProc },
\r
1819 { "InfoProc", InfoProc },
\r
1820 { "ManProc", ManProc },
\r
1821 { "HintProc", HintProc },
\r
1822 { "BookProc", BookProc },
\r
1823 { "AboutGameProc", AboutGameProc },
\r
1824 { "AboutProc", AboutProc },
\r
1825 { "DebugProc", DebugProc },
\r
1826 { "NothingProc", NothingProc },
\r
1827 { "CommentPopDown", (XtActionProc) CommentPopDown },
\r
1828 { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
\r
1829 { "TagsPopDown", (XtActionProc) TagsPopDown },
\r
1830 { "ErrorPopDown", (XtActionProc) ErrorPopDown },
\r
1831 { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
\r
1832 { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
\r
1833 { "FileNamePopDown", (XtActionProc) FileNamePopDown },
\r
1834 { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
\r
1835 { "GameListPopDown", (XtActionProc) GameListPopDown },
\r
1836 { "PromotionPopDown", (XtActionProc) PromotionPopDown },
\r
1837 { "HistoryPopDown", (XtActionProc) HistoryPopDown },
\r
1838 { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
\r
1839 { "ShufflePopDown", (XtActionProc) ShufflePopDown },
\r
1840 { "EnginePopDown", (XtActionProc) EnginePopDown },
\r
1841 { "UciPopDown", (XtActionProc) UciPopDown },
\r
1842 { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
\r
1843 { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
\r
1844 { "SettingsPopDown", (XtActionProc) SettingsPopDown },
\r
1847 char globalTranslations[] =
\r
1848 ":<Key>R: ResignProc() \n \
\r
1849 :<Key>r: ResetProc() \n \
\r
1850 :<Key>g: LoadGameProc() \n \
\r
1851 :<Key>N: LoadNextGameProc() \n \
\r
1852 :<Key>P: LoadPrevGameProc() \n \
\r
1853 :<Key>Q: QuitProc() \n \
\r
1854 :<Key>F: ToEndProc() \n \
\r
1855 :<Key>f: ForwardProc() \n \
\r
1856 :<Key>B: ToStartProc() \n \
\r
1857 :<Key>b: BackwardProc() \n \
\r
1858 :<Key>p: PauseProc() \n \
\r
1859 :<Key>d: DrawProc() \n \
\r
1860 :<Key>t: CallFlagProc() \n \
\r
1861 :<Key>i: Iconify() \n \
\r
1862 :<Key>c: Iconify() \n \
\r
1863 :<Key>v: FlipViewProc() \n \
\r
1864 <KeyDown>Control_L: BackwardProc() \n \
\r
1865 <KeyUp>Control_L: ForwardProc() \n \
\r
1866 <KeyDown>Control_R: BackwardProc() \n \
\r
1867 <KeyUp>Control_R: ForwardProc() \n \
\r
1868 Shift<Key>1: AskQuestionProc(\"Direct command\",\
\r
1869 \"Send to chess program:\",,1) \n \
\r
1870 Shift<Key>2: AskQuestionProc(\"Direct command\",\
\r
1871 \"Send to second chess program:\",,2) \n";
\r
1873 char boardTranslations[] =
\r
1874 "<Btn1Down>: HandleUserMove() \n \
\r
1875 <Btn1Up>: HandleUserMove() \n \
\r
1876 <Btn1Motion>: AnimateUserMove() \n \
\r
1877 Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
\r
1878 PieceMenuPopup(menuB) \n \
\r
1879 Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
\r
1880 PieceMenuPopup(menuW) \n \
\r
1881 Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
\r
1882 PieceMenuPopup(menuW) \n \
\r
1883 Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
\r
1884 PieceMenuPopup(menuB) \n";
\r
1886 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
\r
1887 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
\r
1889 char ICSInputTranslations[] =
\r
1890 "<Key>Return: EnterKeyProc() \n";
\r
1892 String xboardResources[] = {
\r
1893 "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
\r
1894 "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
\r
1895 "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
\r
1900 /* Max possible square size */
\r
1901 #define MAXSQSIZE 256
\r
1903 static int xpm_avail[MAXSQSIZE];
\r
1905 #ifdef HAVE_DIR_STRUCT
\r
1907 /* Extract piece size from filename */
\r
1909 xpm_getsize(name, len, ext)
\r
1920 if ((p=strchr(name, '.')) == NULL ||
\r
1921 StrCaseCmp(p+1, ext) != 0)
\r
1927 while (*p && isdigit(*p))
\r
1934 /* Setup xpm_avail */
\r
1936 xpm_getavail(dirname, ext)
\r
1941 struct dirent *ent;
\r
1944 for (i=0; i<MAXSQSIZE; ++i)
\r
1947 if (appData.debugMode)
\r
1948 fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
\r
1950 dir = opendir(dirname);
\r
1953 fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
\r
1954 programName, dirname);
\r
1958 while ((ent=readdir(dir)) != NULL) {
\r
1959 i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
\r
1960 if (i > 0 && i < MAXSQSIZE)
\r
1970 xpm_print_avail(fp, ext)
\r
1976 fprintf(fp, _("Available `%s' sizes:\n"), ext);
\r
1977 for (i=1; i<MAXSQSIZE; ++i) {
\r
1979 printf("%d\n", i);
\r
1983 /* Return XPM piecesize closest to size */
\r
1985 xpm_closest_to(dirname, size, ext)
\r
1991 int sm_diff = MAXSQSIZE;
\r
1995 xpm_getavail(dirname, ext);
\r
1997 if (appData.debugMode)
\r
1998 xpm_print_avail(stderr, ext);
\r
2000 for (i=1; i<MAXSQSIZE; ++i) {
\r
2001 if (xpm_avail[i]) {
\r
2003 diff = (diff<0) ? -diff : diff;
\r
2004 if (diff < sm_diff) {
\r
2012 fprintf(stderr, _("Error: No `%s' files!\n"), ext);
\r
2018 #else /* !HAVE_DIR_STRUCT */
\r
2019 /* If we are on a system without a DIR struct, we can't
\r
2020 read the directory, so we can't collect a list of
\r
2021 filenames, etc., so we can't do any size-fitting. */
\r
2023 xpm_closest_to(dirname, size, ext)
\r
2028 fprintf(stderr, _("\
\r
2029 Warning: No DIR structure found on this system --\n\
\r
2030 Unable to autosize for XPM/XIM pieces.\n\
\r
2031 Please report this error to frankm@hiwaay.net.\n\
\r
2032 Include system type & operating system in message.\n"));
\r
2035 #endif /* HAVE_DIR_STRUCT */
\r
2037 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
\r
2038 "magenta", "cyan", "white" };
\r
2042 TextColors textColors[(int)NColorClasses];
\r
2044 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
\r
2046 parse_color(str, which)
\r
2050 char *p, buf[100], *d;
\r
2053 if (strlen(str) > 99) /* watch bounds on buf */
\r
2058 for (i=0; i<which; ++i) {
\r
2059 p = strchr(p, ',');
\r
2065 /* Could be looking at something like:
\r
2067 .. in which case we want to stop on a comma also */
\r
2068 while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
\r
2072 return -1; /* Use default for empty field */
\r
2075 if (which == 2 || isdigit(*p))
\r
2078 while (*p && isalpha(*p))
\r
2083 for (i=0; i<8; ++i) {
\r
2084 if (!StrCaseCmp(buf, cnames[i]))
\r
2085 return which? (i+40) : (i+30);
\r
2087 if (!StrCaseCmp(buf, "default")) return -1;
\r
2089 fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
\r
2094 parse_cpair(cc, str)
\r
2098 if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
\r
2099 fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
\r
2100 programName, str);
\r
2104 /* bg and attr are optional */
\r
2105 textColors[(int)cc].bg = parse_color(str, 1);
\r
2106 if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
\r
2107 textColors[(int)cc].attr = 0;
\r
2113 /* Arrange to catch delete-window events */
\r
2114 Atom wm_delete_window;
\r
2116 CatchDeleteWindow(Widget w, String procname)
\r
2118 char buf[MSG_SIZ];
\r
2119 XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
\r
2120 sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
\r
2121 XtAugmentTranslations(w, XtParseTranslationTable(buf));
\r
2128 XtSetArg(args[0], XtNiconic, False);
\r
2129 XtSetValues(shellWidget, args, 1);
\r
2131 XtPopup(shellWidget, XtGrabNone); /* Raise if lowered */
\r
2135 // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
\r
2137 #define BoardSize int
\r
2138 void InitDrawingSizes(BoardSize boardSize, int flags)
\r
2139 { // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
\r
2140 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
\r
2142 XtGeometryResult gres;
\r
2145 if(!formWidget) return;
\r
2148 * Enable shell resizing.
\r
2150 shellArgs[0].value = (XtArgVal) &w;
\r
2151 shellArgs[1].value = (XtArgVal) &h;
\r
2152 XtGetValues(shellWidget, shellArgs, 2);
\r
2154 shellArgs[4].value = 2*w; shellArgs[2].value = 10;
\r
2155 shellArgs[5].value = 2*h; shellArgs[3].value = 10;
\r
2156 XtSetValues(shellWidget, &shellArgs[2], 4);
\r
2158 XtSetArg(args[0], XtNdefaultDistance, &sep);
\r
2159 XtGetValues(formWidget, args, 1);
\r
2161 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
2162 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
2165 XtSetArg(args[0], XtNwidth, boardWidth);
\r
2166 XtSetArg(args[1], XtNheight, boardHeight);
\r
2167 XtSetValues(boardWidget, args, 2);
\r
2169 timerWidth = (boardWidth - sep) / 2;
\r
2170 XtSetArg(args[0], XtNwidth, timerWidth);
\r
2171 XtSetValues(whiteTimerWidget, args, 1);
\r
2172 XtSetValues(blackTimerWidget, args, 1);
\r
2174 XawFormDoLayout(formWidget, False);
\r
2176 if (appData.titleInWindow) {
\r
2178 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2179 XtSetArg(args[i], XtNheight, &h); i++;
\r
2180 XtGetValues(titleWidget, args, i);
\r
2181 if (smallLayout) {
\r
2182 w = boardWidth - 2*bor;
\r
2184 XtSetArg(args[0], XtNwidth, &w);
\r
2185 XtGetValues(menuBarWidget, args, 1);
\r
2186 w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
\r
2189 gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
\r
2190 if (gres != XtGeometryYes && appData.debugMode) {
\r
2192 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
\r
2193 programName, gres, w, h, wr, hr);
\r
2197 XawFormDoLayout(formWidget, True);
\r
2200 * Inhibit shell resizing.
\r
2202 shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
\r
2203 shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
\r
2204 shellArgs[4].value = shellArgs[2].value = w;
\r
2205 shellArgs[5].value = shellArgs[3].value = h;
\r
2206 XtSetValues(shellWidget, &shellArgs[0], 6);
\r
2215 int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
\r
2216 XSetWindowAttributes window_attributes;
\r
2218 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
\r
2219 XrmValue vFrom, vTo;
\r
2220 XtGeometryResult gres;
\r
2223 int forceMono = False;
\r
2224 #define INDIRECTION
\r
2225 #ifdef INDIRECTION
\r
2226 // [HGM] before anything else, expand any indirection files amongst options
\r
2227 char *argvCopy[1000]; // 1000 seems enough
\r
2228 char newArgs[10000]; // holds actual characters
\r
2231 srandom(time(0)); // [HGM] book: make random truly random
\r
2234 for(i=0; i<argc; i++) {
\r
2235 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
\r
2236 //fprintf(stderr, "arg %s\n", argv[i]);
\r
2237 if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
\r
2239 FILE *f = fopen(argv[i]+1, "rb");
\r
2240 if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
\r
2241 argvCopy[j++] = newArgs + k; // get ready for first argument from file
\r
2242 while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
\r
2244 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
\r
2245 newArgs[k++] = 0; // terminate current arg
\r
2246 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
\r
2247 argvCopy[j++] = newArgs + k; // get ready for next
\r
2249 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
\r
2258 argvCopy[j] = NULL;
\r
2262 if(appData.debugMode,1) { // OK, appData is not initialized here yet...
\r
2263 for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
\r
2269 setbuf(stdout, NULL);
\r
2270 setbuf(stderr, NULL);
\r
2273 programName = strrchr(argv[0], '/');
\r
2274 if (programName == NULL)
\r
2275 programName = argv[0];
\r
2280 XtSetLanguageProc(NULL, NULL, NULL);
\r
2281 bindtextdomain(PRODUCT, LOCALEDIR);
\r
2282 textdomain(PRODUCT);
\r
2286 XtAppInitialize(&appContext, "XBoard", shellOptions,
\r
2287 XtNumber(shellOptions),
\r
2288 &argc, argv, xboardResources, NULL, 0);
\r
2290 fprintf(stderr, _("%s: unrecognized argument %s\n"),
\r
2291 programName, argv[1]);
\r
2295 if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
\r
2298 if (chdir(chessDir) != 0) {
\r
2299 fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
\r
2305 p = getenv("HOME");
\r
2306 if (p == NULL) p = "/tmp";
\r
2307 i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
\r
2308 gameCopyFilename = (char*) malloc(i);
\r
2309 gamePasteFilename = (char*) malloc(i);
\r
2310 sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
\r
2311 sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
\r
2313 XtGetApplicationResources(shellWidget, (XtPointer) &appData,
\r
2314 clientResources, XtNumber(clientResources),
\r
2317 if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
\r
2318 /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
\r
2319 if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL) {
\r
2320 printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
\r
2323 setbuf(debugFP, NULL);
\r
2326 /* [HGM,HR] make sure board size is acceptable */
\r
2327 if(appData.NrFiles > BOARD_SIZE ||
\r
2328 appData.NrRanks > BOARD_SIZE )
\r
2329 DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
\r
2332 /* This feature does not work; animation needs a rewrite */
\r
2333 appData.highlightDragging = FALSE;
\r
2337 xDisplay = XtDisplay(shellWidget);
\r
2338 xScreen = DefaultScreen(xDisplay);
\r
2339 wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
\r
2341 gameInfo.variant = StringToVariant(appData.variant);
\r
2342 InitPosition(FALSE);
\r
2345 * Determine boardSize
\r
2347 gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
\r
2350 // [HGM] as long as we have not created the possibility to change size while running, start with requested size
\r
2351 gameInfo.boardWidth = appData.NrFiles > 0 ? appData.NrFiles : 8;
\r
2352 gameInfo.boardHeight = appData.NrRanks > 0 ? appData.NrRanks : 8;
\r
2353 gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
\r
2358 InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
\r
2360 if (isdigit(appData.boardSize[0])) {
\r
2361 i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
\r
2362 &lineGap, &clockFontPxlSize, &coordFontPxlSize,
\r
2363 &fontPxlSize, &smallLayout, &tinyLayout);
\r
2365 fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
\r
2366 programName, appData.boardSize);
\r
2370 /* Find some defaults; use the nearest known size */
\r
2371 SizeDefaults *szd, *nearest;
\r
2372 int distance = 99999;
\r
2373 nearest = szd = sizeDefaults;
\r
2374 while (szd->name != NULL) {
\r
2375 if (abs(szd->squareSize - squareSize) < distance) {
\r
2377 distance = abs(szd->squareSize - squareSize);
\r
2378 if (distance == 0) break;
\r
2382 if (i < 2) lineGap = nearest->lineGap;
\r
2383 if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
\r
2384 if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
\r
2385 if (i < 5) fontPxlSize = nearest->fontPxlSize;
\r
2386 if (i < 6) smallLayout = nearest->smallLayout;
\r
2387 if (i < 7) tinyLayout = nearest->tinyLayout;
\r
2390 SizeDefaults *szd = sizeDefaults;
\r
2391 if (*appData.boardSize == NULLCHAR) {
\r
2392 while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
\r
2393 DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
\r
2396 if (szd->name == NULL) szd--;
\r
2398 while (szd->name != NULL &&
\r
2399 StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
\r
2400 if (szd->name == NULL) {
\r
2401 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
\r
2402 programName, appData.boardSize);
\r
2406 squareSize = szd->squareSize;
\r
2407 lineGap = szd->lineGap;
\r
2408 clockFontPxlSize = szd->clockFontPxlSize;
\r
2409 coordFontPxlSize = szd->coordFontPxlSize;
\r
2410 fontPxlSize = szd->fontPxlSize;
\r
2411 smallLayout = szd->smallLayout;
\r
2412 tinyLayout = szd->tinyLayout;
\r
2415 /* Now, using squareSize as a hint, find a good XPM/XIM set size */
\r
2416 if (strlen(appData.pixmapDirectory) > 0) {
\r
2417 p = ExpandPathName(appData.pixmapDirectory);
\r
2419 fprintf(stderr, _("Error expanding path name \"%s\"\n"),
\r
2420 appData.pixmapDirectory);
\r
2423 if (appData.debugMode) {
\r
2424 fprintf(stderr, _("\
\r
2425 XBoard square size (hint): %d\n\
\r
2426 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
\r
2428 squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
\r
2429 if (appData.debugMode) {
\r
2430 fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
\r
2434 /* [HR] height treated separately (hacked) */
\r
2435 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
2436 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
2437 if (appData.showJail == 1) {
\r
2438 /* Jail on top and bottom */
\r
2439 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
\r
2440 XtSetArg(boardArgs[2], XtNheight,
\r
2441 boardHeight + 2*(lineGap + squareSize));
\r
2442 } else if (appData.showJail == 2) {
\r
2443 /* Jail on sides */
\r
2444 XtSetArg(boardArgs[1], XtNwidth,
\r
2445 boardWidth + 2*(lineGap + squareSize));
\r
2446 XtSetArg(boardArgs[2], XtNheight, boardHeight);
\r
2449 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
\r
2450 XtSetArg(boardArgs[2], XtNheight, boardHeight);
\r
2454 * Determine what fonts to use.
\r
2456 appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
\r
2457 clockFontID = XLoadFont(xDisplay, appData.clockFont);
\r
2458 clockFontStruct = XQueryFont(xDisplay, clockFontID);
\r
2459 appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
\r
2460 coordFontID = XLoadFont(xDisplay, appData.coordFont);
\r
2461 coordFontStruct = XQueryFont(xDisplay, coordFontID);
\r
2462 appData.font = FindFont(appData.font, fontPxlSize);
\r
2463 countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
\r
2464 countFontStruct = XQueryFont(xDisplay, countFontID);
\r
2465 // appData.font = FindFont(appData.font, fontPxlSize);
\r
2467 xdb = XtDatabase(xDisplay);
\r
2468 XrmPutStringResource(&xdb, "*font", appData.font);
\r
2471 * Detect if there are not enough colors available and adapt.
\r
2473 if (DefaultDepth(xDisplay, xScreen) <= 2) {
\r
2474 appData.monoMode = True;
\r
2477 if (!appData.monoMode) {
\r
2478 vFrom.addr = (caddr_t) appData.lightSquareColor;
\r
2479 vFrom.size = strlen(appData.lightSquareColor);
\r
2480 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2481 if (vTo.addr == NULL) {
\r
2482 appData.monoMode = True;
\r
2485 lightSquareColor = *(Pixel *) vTo.addr;
\r
2488 if (!appData.monoMode) {
\r
2489 vFrom.addr = (caddr_t) appData.darkSquareColor;
\r
2490 vFrom.size = strlen(appData.darkSquareColor);
\r
2491 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2492 if (vTo.addr == NULL) {
\r
2493 appData.monoMode = True;
\r
2496 darkSquareColor = *(Pixel *) vTo.addr;
\r
2499 if (!appData.monoMode) {
\r
2500 vFrom.addr = (caddr_t) appData.whitePieceColor;
\r
2501 vFrom.size = strlen(appData.whitePieceColor);
\r
2502 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2503 if (vTo.addr == NULL) {
\r
2504 appData.monoMode = True;
\r
2507 whitePieceColor = *(Pixel *) vTo.addr;
\r
2510 if (!appData.monoMode) {
\r
2511 vFrom.addr = (caddr_t) appData.blackPieceColor;
\r
2512 vFrom.size = strlen(appData.blackPieceColor);
\r
2513 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2514 if (vTo.addr == NULL) {
\r
2515 appData.monoMode = True;
\r
2518 blackPieceColor = *(Pixel *) vTo.addr;
\r
2522 if (!appData.monoMode) {
\r
2523 vFrom.addr = (caddr_t) appData.highlightSquareColor;
\r
2524 vFrom.size = strlen(appData.highlightSquareColor);
\r
2525 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2526 if (vTo.addr == NULL) {
\r
2527 appData.monoMode = True;
\r
2530 highlightSquareColor = *(Pixel *) vTo.addr;
\r
2534 if (!appData.monoMode) {
\r
2535 vFrom.addr = (caddr_t) appData.premoveHighlightColor;
\r
2536 vFrom.size = strlen(appData.premoveHighlightColor);
\r
2537 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2538 if (vTo.addr == NULL) {
\r
2539 appData.monoMode = True;
\r
2542 premoveHighlightColor = *(Pixel *) vTo.addr;
\r
2547 fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
\r
2551 if (appData.monoMode && appData.debugMode) {
\r
2552 fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
\r
2553 (unsigned long) XWhitePixel(xDisplay, xScreen),
\r
2554 (unsigned long) XBlackPixel(xDisplay, xScreen));
\r
2557 if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
\r
2558 parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
\r
2559 parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||
\r
2560 parse_cpair(ColorChannel, appData.colorChannel) < 0 ||
\r
2561 parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
\r
2562 parse_cpair(ColorTell, appData.colorTell) < 0 ||
\r
2563 parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||
\r
2564 parse_cpair(ColorRequest, appData.colorRequest) < 0 ||
\r
2565 parse_cpair(ColorSeek, appData.colorSeek) < 0 ||
\r
2566 parse_cpair(ColorNormal, appData.colorNormal) < 0)
\r
2568 if (appData.colorize) {
\r
2570 _("%s: can't parse color names; disabling colorization\n"),
\r
2573 appData.colorize = FALSE;
\r
2575 textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
\r
2576 textColors[ColorNone].attr = 0;
\r
2578 XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
\r
2581 * widget hierarchy
\r
2584 layoutName = "tinyLayout";
\r
2585 } else if (smallLayout) {
\r
2586 layoutName = "smallLayout";
\r
2588 layoutName = "normalLayout";
\r
2590 /* Outer layoutWidget is there only to provide a name for use in
\r
2591 resources that depend on the layout style */
\r
2593 XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
\r
2594 layoutArgs, XtNumber(layoutArgs));
\r
2596 XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
\r
2597 formArgs, XtNumber(formArgs));
\r
2598 XtSetArg(args[0], XtNdefaultDistance, &sep);
\r
2599 XtGetValues(formWidget, args, 1);
\r
2602 widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
\r
2603 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2604 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2605 XtSetValues(menuBarWidget, args, 2);
\r
2607 widgetList[j++] = whiteTimerWidget =
\r
2608 XtCreateWidget("whiteTime", labelWidgetClass,
\r
2609 formWidget, timerArgs, XtNumber(timerArgs));
\r
2610 XtSetArg(args[0], XtNfont, clockFontStruct);
\r
2611 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2612 XtSetArg(args[2], XtNbottom, XtChainTop);
\r
2613 XtSetValues(whiteTimerWidget, args, 3);
\r
2615 widgetList[j++] = blackTimerWidget =
\r
2616 XtCreateWidget("blackTime", labelWidgetClass,
\r
2617 formWidget, timerArgs, XtNumber(timerArgs));
\r
2618 XtSetArg(args[0], XtNfont, clockFontStruct);
\r
2619 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2620 XtSetArg(args[2], XtNbottom, XtChainTop);
\r
2621 XtSetValues(blackTimerWidget, args, 3);
\r
2623 if (appData.titleInWindow) {
\r
2624 widgetList[j++] = titleWidget =
\r
2625 XtCreateWidget("title", labelWidgetClass, formWidget,
\r
2626 titleArgs, XtNumber(titleArgs));
\r
2627 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2628 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2629 XtSetValues(titleWidget, args, 2);
\r
2632 if (appData.showButtonBar) {
\r
2633 widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
\r
2634 XtSetArg(args[0], XtNleft, XtChainRight); // [HGM] glue to right window edge
\r
2635 XtSetArg(args[1], XtNright, XtChainRight); // for good run-time sizing
\r
2636 XtSetArg(args[2], XtNtop, XtChainTop);
\r
2637 XtSetArg(args[3], XtNbottom, XtChainTop);
\r
2638 XtSetValues(buttonBarWidget, args, 4);
\r
2641 widgetList[j++] = messageWidget =
\r
2642 XtCreateWidget("message", labelWidgetClass, formWidget,
\r
2643 messageArgs, XtNumber(messageArgs));
\r
2644 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2645 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2646 XtSetValues(messageWidget, args, 2);
\r
2648 widgetList[j++] = boardWidget =
\r
2649 XtCreateWidget("board", widgetClass, formWidget, boardArgs,
\r
2650 XtNumber(boardArgs));
\r
2652 XtManageChildren(widgetList, j);
\r
2654 timerWidth = (boardWidth - sep) / 2;
\r
2655 XtSetArg(args[0], XtNwidth, timerWidth);
\r
2656 XtSetValues(whiteTimerWidget, args, 1);
\r
2657 XtSetValues(blackTimerWidget, args, 1);
\r
2659 XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
\r
2660 XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
\r
2661 XtGetValues(whiteTimerWidget, args, 2);
\r
2663 if (appData.showButtonBar) {
\r
2664 XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
\r
2665 XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
\r
2666 XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
\r
2670 * formWidget uses these constraints but they are stored
\r
2671 * in the children.
\r
2674 XtSetArg(args[i], XtNfromHoriz, 0); i++;
\r
2675 XtSetValues(menuBarWidget, args, i);
\r
2676 if (appData.titleInWindow) {
\r
2677 if (smallLayout) {
\r
2679 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2680 XtSetValues(whiteTimerWidget, args, i);
\r
2682 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2683 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2684 XtSetValues(blackTimerWidget, args, i);
\r
2686 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2687 XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
\r
2688 XtSetValues(titleWidget, args, i);
\r
2690 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2691 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2692 XtSetValues(messageWidget, args, i);
\r
2693 if (appData.showButtonBar) {
\r
2695 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2696 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2697 XtSetValues(buttonBarWidget, args, i);
\r
2701 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2702 XtSetValues(whiteTimerWidget, args, i);
\r
2704 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2705 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2706 XtSetValues(blackTimerWidget, args, i);
\r
2708 XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
\r
2709 XtSetValues(titleWidget, args, i);
\r
2711 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2712 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2713 XtSetValues(messageWidget, args, i);
\r
2714 if (appData.showButtonBar) {
\r
2716 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2717 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2718 XtSetValues(buttonBarWidget, args, i);
\r
2723 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2724 XtSetValues(whiteTimerWidget, args, i);
\r
2726 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2727 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2728 XtSetValues(blackTimerWidget, args, i);
\r
2730 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2731 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2732 XtSetValues(messageWidget, args, i);
\r
2733 if (appData.showButtonBar) {
\r
2735 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2736 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2737 XtSetValues(buttonBarWidget, args, i);
\r
2741 XtSetArg(args[0], XtNfromVert, messageWidget);
\r
2742 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2743 XtSetArg(args[2], XtNbottom, XtChainBottom);
\r
2744 XtSetArg(args[3], XtNleft, XtChainLeft);
\r
2745 XtSetArg(args[4], XtNright, XtChainRight);
\r
2746 XtSetValues(boardWidget, args, 5);
\r
2748 XtRealizeWidget(shellWidget);
\r
2751 * Correct the width of the message and title widgets.
\r
2752 * It is not known why some systems need the extra fudge term.
\r
2753 * The value "2" is probably larger than needed.
\r
2755 XawFormDoLayout(formWidget, False);
\r
2757 #define WIDTH_FUDGE 2
\r
2759 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2760 XtSetArg(args[i], XtNheight, &h); i++;
\r
2761 XtGetValues(messageWidget, args, i);
\r
2762 if (appData.showButtonBar) {
\r
2764 XtSetArg(args[i], XtNwidth, &w); i++;
\r
2765 XtGetValues(buttonBarWidget, args, i);
\r
2766 w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
\r
2768 w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
\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 /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
\r
2778 /* The size used for the child widget in layout lags one resize behind
\r
2779 its true size, so we resize a second time, 1 pixel smaller. Yeech! */
\r
2781 gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
\r
2782 if (gres != XtGeometryYes && appData.debugMode) {
\r
2783 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
\r
2784 programName, gres, w, h, wr, hr);
\r
2787 XtSetArg(args[0], XtNleft, XtChainLeft); // [HGM] glue ends for good run-time sizing
\r
2788 XtSetArg(args[1], XtNright, XtChainRight);
\r
2789 XtSetValues(messageWidget, args, 2);
\r
2791 if (appData.titleInWindow) {
\r
2793 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2794 XtSetArg(args[i], XtNheight, &h); i++;
\r
2795 XtGetValues(titleWidget, args, i);
\r
2796 if (smallLayout) {
\r
2797 w = boardWidth - 2*bor;
\r
2799 XtSetArg(args[0], XtNwidth, &w);
\r
2800 XtGetValues(menuBarWidget, args, 1);
\r
2801 w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
\r
2804 gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
\r
2805 if (gres != XtGeometryYes && appData.debugMode) {
\r
2807 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
\r
2808 programName, gres, w, h, wr, hr);
\r
2811 XawFormDoLayout(formWidget, True);
\r
2813 xBoardWindow = XtWindow(boardWidget);
\r
2815 // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
\r
2816 // not need to go into InitDrawingSizes().
\r
2820 * Create X checkmark bitmap and initialize option menu checks.
\r
2822 ReadBitmap(&xMarkPixmap, "checkmark.bm",
\r
2823 checkmark_bits, checkmark_width, checkmark_height);
\r
2824 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
2825 if (appData.alwaysPromoteToQueen) {
\r
2826 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
\r
2829 if (appData.animateDragging) {
\r
2830 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2831 "menuOptions.Animate Dragging"),
\r
2834 if (appData.animate) {
\r
2835 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
\r
2838 if (appData.autoComment) {
\r
2839 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
\r
2842 if (appData.autoCallFlag) {
\r
2843 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
\r
2846 if (appData.autoFlipView) {
\r
2847 XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
\r
2850 if (appData.autoObserve) {
\r
2851 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
\r
2854 if (appData.autoRaiseBoard) {
\r
2855 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2856 "menuOptions.Auto Raise Board"), args, 1);
\r
2858 if (appData.autoSaveGames) {
\r
2859 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2862 if (appData.saveGameFile[0] != NULLCHAR) {
\r
2863 /* Can't turn this off from menu */
\r
2864 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2866 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2870 if (appData.blindfold) {
\r
2871 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2872 "menuOptions.Blindfold"), args, 1);
\r
2874 if (appData.flashCount > 0) {
\r
2875 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2876 "menuOptions.Flash Moves"),
\r
2879 if (appData.getMoveList) {
\r
2880 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
\r
2884 if (appData.highlightDragging) {
\r
2885 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2886 "menuOptions.Highlight Dragging"),
\r
2890 if (appData.highlightLastMove) {
\r
2891 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2892 "menuOptions.Highlight Last Move"),
\r
2895 if (appData.icsAlarm) {
\r
2896 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
\r
2899 if (appData.ringBellAfterMoves) {
\r
2900 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
\r
2903 if (appData.oldSaveStyle) {
\r
2904 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2905 "menuOptions.Old Save Style"), args, 1);
\r
2907 if (appData.periodicUpdates) {
\r
2908 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2909 "menuOptions.Periodic Updates"), args, 1);
\r
2911 if (appData.ponderNextMove) {
\r
2912 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2913 "menuOptions.Ponder Next Move"), args, 1);
\r
2915 if (appData.popupExitMessage) {
\r
2916 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2917 "menuOptions.Popup Exit Message"), args, 1);
\r
2919 if (appData.popupMoveErrors) {
\r
2920 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2921 "menuOptions.Popup Move Errors"), args, 1);
\r
2923 if (appData.premove) {
\r
2924 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2925 "menuOptions.Premove"), args, 1);
\r
2927 if (appData.quietPlay) {
\r
2928 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2929 "menuOptions.Quiet Play"), args, 1);
\r
2931 if (appData.showCoords) {
\r
2932 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
\r
2935 if (appData.hideThinkingFromHuman) {
\r
2936 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
\r
2939 if (appData.testLegality) {
\r
2940 XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
\r
2947 ReadBitmap(&wIconPixmap, "icon_white.bm",
\r
2948 icon_white_bits, icon_white_width, icon_white_height);
\r
2949 ReadBitmap(&bIconPixmap, "icon_black.bm",
\r
2950 icon_black_bits, icon_black_width, icon_black_height);
\r
2951 iconPixmap = wIconPixmap;
\r
2953 XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;
\r
2954 XtSetValues(shellWidget, args, i);
\r
2957 * Create a cursor for the board widget.
\r
2959 window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
\r
2960 XChangeWindowAttributes(xDisplay, xBoardWindow,
\r
2961 CWCursor, &window_attributes);
\r
2964 * Inhibit shell resizing.
\r
2966 shellArgs[0].value = (XtArgVal) &w;
\r
2967 shellArgs[1].value = (XtArgVal) &h;
\r
2968 XtGetValues(shellWidget, shellArgs, 2);
\r
2969 shellArgs[4].value = shellArgs[2].value = w;
\r
2970 shellArgs[5].value = shellArgs[3].value = h;
\r
2971 XtSetValues(shellWidget, &shellArgs[2], 4);
\r
2972 marginW = w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
\r
2973 marginH = h - boardHeight;
\r
2975 CatchDeleteWindow(shellWidget, "QuitProc");
\r
2980 if (appData.bitmapDirectory[0] != NULLCHAR) {
\r
2983 CreateXPMPieces();
\r
2986 CreateXIMPieces();
\r
2987 /* Create regular pieces */
\r
2988 if (!useImages) CreatePieces();
\r
2991 CreatePieceMenus();
\r
2993 if (appData.animate || appData.animateDragging)
\r
2996 XtAugmentTranslations(formWidget,
\r
2997 XtParseTranslationTable(globalTranslations));
\r
2998 XtAugmentTranslations(boardWidget,
\r
2999 XtParseTranslationTable(boardTranslations));
\r
3000 XtAugmentTranslations(whiteTimerWidget,
\r
3001 XtParseTranslationTable(whiteTranslations));
\r
3002 XtAugmentTranslations(blackTimerWidget,
\r
3003 XtParseTranslationTable(blackTranslations));
\r
3005 /* Why is the following needed on some versions of X instead
\r
3006 * of a translation? */
\r
3007 XtAddEventHandler(boardWidget, ExposureMask, False,
\r
3008 (XtEventHandler) EventProc, NULL);
\r
3013 if (errorExitStatus == -1) {
\r
3014 if (appData.icsActive) {
\r
3015 /* We now wait until we see "login:" from the ICS before
\r
3016 sending the logon script (problems with timestamp otherwise) */
\r
3017 /*ICSInitScript();*/
\r
3018 if (appData.icsInputBox) ICSInputBoxPopUp();
\r
3021 signal(SIGINT, IntSigHandler);
\r
3022 signal(SIGTERM, IntSigHandler);
\r
3023 if (*appData.cmailGameName != NULLCHAR) {
\r
3024 signal(SIGUSR1, CmailSigHandler);
\r
3027 InitPosition(TRUE);
\r
3029 XtAppMainLoop(appContext);
\r
3030 if (appData.debugMode) fclose(debugFP); // [DM] debug
\r
3035 ShutDownFrontEnd()
\r
3037 if (appData.icsActive && oldICSInteractionTitle != NULL) {
\r
3038 DisplayIcsInteractionTitle(oldICSInteractionTitle);
\r
3040 unlink(gameCopyFilename);
\r
3041 unlink(gamePasteFilename);
\r
3045 IntSigHandler(sig)
\r
3052 CmailSigHandler(sig)
\r
3058 signal(SIGUSR1, SIG_IGN); /* suspend handler */
\r
3060 /* Activate call-back function CmailSigHandlerCallBack() */
\r
3061 OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
\r
3063 signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
\r
3067 CmailSigHandlerCallBack(isr, closure, message, count, error)
\r
3068 InputSourceRef isr;
\r
3075 ReloadCmailMsgEvent(TRUE); /* Reload cmail msg */
\r
3077 /**** end signal code ****/
\r
3084 char buf[MSG_SIZ];
\r
3087 f = fopen(appData.icsLogon, "r");
\r
3089 p = getenv("HOME");
\r
3093 strcat(buf, appData.icsLogon);
\r
3094 f = fopen(buf, "r");
\r
3098 ProcessICSInitScript(f);
\r
3105 EditCommentPopDown();
\r
3116 SetMenuEnables(enab)
\r
3120 if (!menuBarWidget) return;
\r
3121 while (enab->name != NULL) {
\r
3122 w = XtNameToWidget(menuBarWidget, enab->name);
\r
3124 DisplayError(enab->name, 0);
\r
3126 XtSetSensitive(w, enab->value);
\r
3132 Enables icsEnables[] = {
\r
3133 { "menuFile.Mail Move", False },
\r
3134 { "menuFile.Reload CMail Message", False },
\r
3135 { "menuMode.Machine Black", False },
\r
3136 { "menuMode.Machine White", False },
\r
3137 { "menuMode.Analysis Mode", False },
\r
3138 { "menuMode.Analyze File", False },
\r
3139 { "menuMode.Two Machines", False },
\r
3141 { "menuHelp.Hint", False },
\r
3142 { "menuHelp.Book", False },
\r
3143 { "menuStep.Move Now", False },
\r
3144 { "menuOptions.Periodic Updates", False },
\r
3145 { "menuOptions.Hide Thinking", False },
\r
3146 { "menuOptions.Ponder Next Move", False },
\r
3151 Enables ncpEnables[] = {
\r
3152 { "menuFile.Mail Move", False },
\r
3153 { "menuFile.Reload CMail Message", False },
\r
3154 { "menuMode.Machine White", False },
\r
3155 { "menuMode.Machine Black", False },
\r
3156 { "menuMode.Analysis Mode", False },
\r
3157 { "menuMode.Analyze File", False },
\r
3158 { "menuMode.Two Machines", False },
\r
3159 { "menuMode.ICS Client", False },
\r
3160 { "menuMode.ICS Input Box", False },
\r
3161 { "Action", False },
\r
3162 { "menuStep.Revert", False },
\r
3163 { "menuStep.Move Now", False },
\r
3164 { "menuStep.Retract Move", False },
\r
3165 { "menuOptions.Auto Comment", False },
\r
3166 { "menuOptions.Auto Flag", False },
\r
3167 { "menuOptions.Auto Flip View", False },
\r
3168 { "menuOptions.Auto Observe", False },
\r
3169 { "menuOptions.Auto Raise Board", False },
\r
3170 { "menuOptions.Get Move List", False },
\r
3171 { "menuOptions.ICS Alarm", False },
\r
3172 { "menuOptions.Move Sound", False },
\r
3173 { "menuOptions.Quiet Play", False },
\r
3174 { "menuOptions.Hide Thinking", False },
\r
3175 { "menuOptions.Periodic Updates", False },
\r
3176 { "menuOptions.Ponder Next Move", False },
\r
3177 { "menuHelp.Hint", False },
\r
3178 { "menuHelp.Book", False },
\r
3182 Enables gnuEnables[] = {
\r
3183 { "menuMode.ICS Client", False },
\r
3184 { "menuMode.ICS Input Box", False },
\r
3185 { "menuAction.Accept", False },
\r
3186 { "menuAction.Decline", False },
\r
3187 { "menuAction.Rematch", False },
\r
3188 { "menuAction.Adjourn", False },
\r
3189 { "menuAction.Stop Examining", False },
\r
3190 { "menuAction.Stop Observing", False },
\r
3191 { "menuStep.Revert", False },
\r
3192 { "menuOptions.Auto Comment", False },
\r
3193 { "menuOptions.Auto Observe", False },
\r
3194 { "menuOptions.Auto Raise Board", False },
\r
3195 { "menuOptions.Get Move List", False },
\r
3196 { "menuOptions.Premove", False },
\r
3197 { "menuOptions.Quiet Play", False },
\r
3199 /* The next two options rely on SetCmailMode being called *after* */
\r
3200 /* SetGNUMode so that when GNU is being used to give hints these */
\r
3201 /* menu options are still available */
\r
3203 { "menuFile.Mail Move", False },
\r
3204 { "menuFile.Reload CMail Message", False },
\r
3208 Enables cmailEnables[] = {
\r
3209 { "Action", True },
\r
3210 { "menuAction.Call Flag", False },
\r
3211 { "menuAction.Draw", True },
\r
3212 { "menuAction.Adjourn", False },
\r
3213 { "menuAction.Abort", False },
\r
3214 { "menuAction.Stop Observing", False },
\r
3215 { "menuAction.Stop Examining", False },
\r
3216 { "menuFile.Mail Move", True },
\r
3217 { "menuFile.Reload CMail Message", True },
\r
3221 Enables trainingOnEnables[] = {
\r
3222 { "menuMode.Edit Comment", False },
\r
3223 { "menuMode.Pause", False },
\r
3224 { "menuStep.Forward", False },
\r
3225 { "menuStep.Backward", False },
\r
3226 { "menuStep.Forward to End", False },
\r
3227 { "menuStep.Back to Start", False },
\r
3228 { "menuStep.Move Now", False },
\r
3229 { "menuStep.Truncate Game", False },
\r
3233 Enables trainingOffEnables[] = {
\r
3234 { "menuMode.Edit Comment", True },
\r
3235 { "menuMode.Pause", True },
\r
3236 { "menuStep.Forward", True },
\r
3237 { "menuStep.Backward", True },
\r
3238 { "menuStep.Forward to End", True },
\r
3239 { "menuStep.Back to Start", True },
\r
3240 { "menuStep.Move Now", True },
\r
3241 { "menuStep.Truncate Game", True },
\r
3245 Enables machineThinkingEnables[] = {
\r
3246 { "menuFile.Load Game", False },
\r
3247 { "menuFile.Load Next Game", False },
\r
3248 { "menuFile.Load Previous Game", False },
\r
3249 { "menuFile.Reload Same Game", False },
\r
3250 { "menuFile.Paste Game", False },
\r
3251 { "menuFile.Load Position", False },
\r
3252 { "menuFile.Load Next Position", False },
\r
3253 { "menuFile.Load Previous Position", False },
\r
3254 { "menuFile.Reload Same Position", False },
\r
3255 { "menuFile.Paste Position", False },
\r
3256 { "menuMode.Machine White", False },
\r
3257 { "menuMode.Machine Black", False },
\r
3258 { "menuMode.Two Machines", False },
\r
3259 { "menuStep.Retract Move", False },
\r
3263 Enables userThinkingEnables[] = {
\r
3264 { "menuFile.Load Game", True },
\r
3265 { "menuFile.Load Next Game", True },
\r
3266 { "menuFile.Load Previous Game", True },
\r
3267 { "menuFile.Reload Same Game", True },
\r
3268 { "menuFile.Paste Game", True },
\r
3269 { "menuFile.Load Position", True },
\r
3270 { "menuFile.Load Next Position", True },
\r
3271 { "menuFile.Load Previous Position", True },
\r
3272 { "menuFile.Reload Same Position", True },
\r
3273 { "menuFile.Paste Position", True },
\r
3274 { "menuMode.Machine White", True },
\r
3275 { "menuMode.Machine Black", True },
\r
3276 { "menuMode.Two Machines", True },
\r
3277 { "menuStep.Retract Move", True },
\r
3283 SetMenuEnables(icsEnables);
\r
3286 if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */
\r
3287 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
\r
3294 SetMenuEnables(ncpEnables);
\r
3300 SetMenuEnables(gnuEnables);
\r
3306 SetMenuEnables(cmailEnables);
\r
3310 SetTrainingModeOn()
\r
3312 SetMenuEnables(trainingOnEnables);
\r
3313 if (appData.showButtonBar) {
\r
3314 XtSetSensitive(buttonBarWidget, False);
\r
3320 SetTrainingModeOff()
\r
3322 SetMenuEnables(trainingOffEnables);
\r
3323 if (appData.showButtonBar) {
\r
3324 XtSetSensitive(buttonBarWidget, True);
\r
3329 SetUserThinkingEnables()
\r
3331 if (appData.noChessProgram) return;
\r
3332 SetMenuEnables(userThinkingEnables);
\r
3336 SetMachineThinkingEnables()
\r
3338 if (appData.noChessProgram) return;
\r
3339 SetMenuEnables(machineThinkingEnables);
\r
3340 switch (gameMode) {
\r
3341 case MachinePlaysBlack:
\r
3342 case MachinePlaysWhite:
\r
3343 case TwoMachinesPlay:
\r
3344 XtSetSensitive(XtNameToWidget(menuBarWidget,
\r
3345 ModeToWidgetName(gameMode)), True);
\r
3352 #define Abs(n) ((n)<0 ? -(n) : (n))
\r
3355 * Find a font that matches "pattern" that is as close as
\r
3356 * possible to the targetPxlSize. Prefer fonts that are k
\r
3357 * pixels smaller to fonts that are k pixels larger. The
\r
3358 * pattern must be in the X Consortium standard format,
\r
3359 * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
\r
3360 * The return value should be freed with XtFree when no
\r
3363 char *FindFont(pattern, targetPxlSize)
\r
3365 int targetPxlSize;
\r
3367 char **fonts, *p, *best, *scalable, *scalableTail;
\r
3368 int i, j, nfonts, minerr, err, pxlSize;
\r
3371 char **missing_list;
\r
3372 int missing_count;
\r
3373 char *def_string, *base_fnt_lst, strInt[3];
\r
3375 XFontStruct **fnt_list;
\r
3377 base_fnt_lst = calloc(1, strlen(pattern) + 3);
\r
3378 sprintf(strInt, "%d", targetPxlSize);
\r
3379 p = strstr(pattern, "--");
\r
3380 strncpy(base_fnt_lst, pattern, p - pattern + 2);
\r
3381 strcat(base_fnt_lst, strInt);
\r
3382 strcat(base_fnt_lst, strchr(p + 2, '-'));
\r
3384 if ((fntSet = XCreateFontSet(xDisplay,
\r
3388 &def_string)) == NULL) {
\r
3390 fprintf(stderr, _("Unable to create font set.\n"));
\r
3394 nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
\r
3396 fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
\r
3398 fprintf(stderr, _("%s: no fonts match pattern %s\n"),
\r
3399 programName, pattern);
\r
3407 for (i=0; i<nfonts; i++) {
\r
3410 if (*p != '-') continue;
\r
3412 if (*p == NULLCHAR) break;
\r
3413 if (*p++ == '-') j++;
\r
3415 if (j < 7) continue;
\r
3416 pxlSize = atoi(p);
\r
3417 if (pxlSize == 0) {
\r
3418 scalable = fonts[i];
\r
3421 err = pxlSize - targetPxlSize;
\r
3422 if (Abs(err) < Abs(minerr) ||
\r
3423 (minerr > 0 && err < 0 && -err == minerr)) {
\r
3429 if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
\r
3430 /* If the error is too big and there is a scalable font,
\r
3431 use the scalable font. */
\r
3432 int headlen = scalableTail - scalable;
\r
3433 p = (char *) XtMalloc(strlen(scalable) + 10);
\r
3434 while (isdigit(*scalableTail)) scalableTail++;
\r
3435 sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
\r
3437 p = (char *) XtMalloc(strlen(best) + 1);
\r
3440 if (appData.debugMode) {
\r
3441 fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"),
\r
3442 pattern, targetPxlSize, p);
\r
3445 if (missing_count > 0)
\r
3446 XFreeStringList(missing_list);
\r
3447 XFreeFontSet(xDisplay, fntSet);
\r
3449 XFreeFontNames(fonts);
\r
3456 XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
\r
3457 | GCBackground | GCFunction | GCPlaneMask;
\r
3458 XGCValues gc_values;
\r
3459 GC copyInvertedGC;
\r
3461 gc_values.plane_mask = AllPlanes;
\r
3462 gc_values.line_width = lineGap;
\r
3463 gc_values.line_style = LineSolid;
\r
3464 gc_values.function = GXcopy;
\r
3466 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3467 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3468 lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3470 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3471 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3472 coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3473 XSetFont(xDisplay, coordGC, coordFontID);
\r
3475 // [HGM] make font for holdings counts (white on black0
\r
3476 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3477 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3478 countGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3479 XSetFont(xDisplay, countGC, countFontID);
\r
3481 if (appData.monoMode) {
\r
3482 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3483 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3484 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3486 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3487 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3488 lightSquareGC = wbPieceGC
\r
3489 = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3491 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3492 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3493 darkSquareGC = bwPieceGC
\r
3494 = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3496 if (DefaultDepth(xDisplay, xScreen) == 1) {
\r
3497 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
\r
3498 gc_values.function = GXcopyInverted;
\r
3499 copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3500 gc_values.function = GXcopy;
\r
3501 if (XBlackPixel(xDisplay, xScreen) == 1) {
\r
3502 bwPieceGC = darkSquareGC;
\r
3503 wbPieceGC = copyInvertedGC;
\r
3505 bwPieceGC = copyInvertedGC;
\r
3506 wbPieceGC = lightSquareGC;
\r
3510 gc_values.foreground = highlightSquareColor;
\r
3511 gc_values.background = highlightSquareColor;
\r
3512 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3514 gc_values.foreground = premoveHighlightColor;
\r
3515 gc_values.background = premoveHighlightColor;
\r
3516 prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3518 gc_values.foreground = lightSquareColor;
\r
3519 gc_values.background = darkSquareColor;
\r
3520 lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3522 gc_values.foreground = darkSquareColor;
\r
3523 gc_values.background = lightSquareColor;
\r
3524 darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3526 gc_values.foreground = jailSquareColor;
\r
3527 gc_values.background = jailSquareColor;
\r
3528 jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3530 gc_values.foreground = whitePieceColor;
\r
3531 gc_values.background = darkSquareColor;
\r
3532 wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3534 gc_values.foreground = whitePieceColor;
\r
3535 gc_values.background = lightSquareColor;
\r
3536 wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3538 gc_values.foreground = whitePieceColor;
\r
3539 gc_values.background = jailSquareColor;
\r
3540 wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3542 gc_values.foreground = blackPieceColor;
\r
3543 gc_values.background = darkSquareColor;
\r
3544 bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3546 gc_values.foreground = blackPieceColor;
\r
3547 gc_values.background = lightSquareColor;
\r
3548 blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3550 gc_values.foreground = blackPieceColor;
\r
3551 gc_values.background = jailSquareColor;
\r
3552 bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3556 void loadXIM(xim, xmask, filename, dest, mask)
\r
3563 int x, y, w, h, p;
\r
3569 fp = fopen(filename, "rb");
\r
3571 fprintf(stderr, _("%s: error loading XIM!\n"), programName);
\r
3578 for (y=0; y<h; ++y) {
\r
3579 for (x=0; x<h; ++x) {
\r
3584 XPutPixel(xim, x, y, blackPieceColor);
\r
3586 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
\r
3589 XPutPixel(xim, x, y, darkSquareColor);
\r
3591 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
\r
3594 XPutPixel(xim, x, y, whitePieceColor);
\r
3596 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
\r
3599 XPutPixel(xim, x, y, lightSquareColor);
\r
3601 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
\r
3607 /* create Pixmap of piece */
\r
3608 *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3609 w, h, xim->depth);
\r
3610 XPutImage(xDisplay, *dest, lightSquareGC, xim,
\r
3611 0, 0, 0, 0, w, h);
\r
3613 /* create Pixmap of clipmask
\r
3614 Note: We assume the white/black pieces have the same
\r
3615 outline, so we make only 6 masks. This is okay
\r
3616 since the XPM clipmask routines do the same. */
\r
3618 temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3619 w, h, xim->depth);
\r
3620 XPutImage(xDisplay, temp, lightSquareGC, xmask,
\r
3621 0, 0, 0, 0, w, h);
\r
3623 /* now create the 1-bit version */
\r
3624 *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3627 values.foreground = 1;
\r
3628 values.background = 0;
\r
3630 /* Don't use XtGetGC, not read only */
\r
3631 maskGC = XCreateGC(xDisplay, *mask,
\r
3632 GCForeground | GCBackground, &values);
\r
3633 XCopyPlane(xDisplay, temp, *mask, maskGC,
\r
3634 0, 0, squareSize, squareSize, 0, 0, 1);
\r
3635 XFreePixmap(xDisplay, temp);
\r
3639 void CreateXIMPieces()
\r
3642 char buf[MSG_SIZ];
\r
3644 static char *ximkind[] = { "ll", "ld", "dl", "dd" };
\r
3649 /* The XSynchronize calls were copied from CreatePieces.
\r
3650 Not sure if needed, but can't hurt */
\r
3651 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3654 /* temp needed by loadXIM() */
\r
3655 ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3656 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3658 if (strlen(appData.pixmapDirectory) == 0) {
\r
3662 if (appData.monoMode) {
\r
3663 DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
\r
3667 fprintf(stderr, _("\nLoading XIMs...\n"));
\r
3669 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3670 fprintf(stderr, "%d", piece+1);
\r
3671 for (kind=0; kind<4; kind++) {
\r
3672 fprintf(stderr, ".");
\r
3673 sprintf(buf, "%s/%c%s%u.xim",
\r
3674 ExpandPathName(appData.pixmapDirectory),
\r
3675 ToLower(PieceToChar((ChessSquare)piece)),
\r
3676 ximkind[kind], ss);
\r
3677 ximPieceBitmap[kind][piece] =
\r
3678 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3679 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3680 if (appData.debugMode)
\r
3681 fprintf(stderr, _("(File:%s:) "), buf);
\r
3682 loadXIM(ximPieceBitmap[kind][piece],
\r
3684 &(xpmPieceBitmap[kind][piece]),
\r
3685 &(ximMaskPm[piece%(int)BlackPawn]));
\r
3687 fprintf(stderr," ");
\r
3689 /* Load light and dark squares */
\r
3690 /* If the LSQ and DSQ pieces don't exist, we will
\r
3691 draw them with solid squares. */
\r
3692 sprintf(buf, "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
\r
3693 if (access(buf, 0) != 0) {
\r
3697 fprintf(stderr, _("light square "));
\r
3699 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3700 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3701 if (appData.debugMode)
\r
3702 fprintf(stderr, _("(File:%s:) "), buf);
\r
3704 loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
\r
3705 fprintf(stderr, _("dark square "));
\r
3706 sprintf(buf, "%s/dsq%u.xim",
\r
3707 ExpandPathName(appData.pixmapDirectory), ss);
\r
3708 if (appData.debugMode)
\r
3709 fprintf(stderr, _("(File:%s:) "), buf);
\r
3711 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3712 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3713 loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
\r
3714 xpmJailSquare = xpmLightSquare;
\r
3716 fprintf(stderr, _("Done.\n"));
\r
3718 XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
\r
3722 void CreateXPMPieces()
\r
3724 int piece, kind, r;
\r
3725 char buf[MSG_SIZ];
\r
3726 u_int ss = squareSize;
\r
3727 XpmAttributes attr;
\r
3728 static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
\r
3729 XpmColorSymbol symbols[4];
\r
3732 /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
\r
3733 if (appData.debugMode) {
\r
3734 fprintf(stderr, "XPM Library Version: %d.%d%c\n",
\r
3735 XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
\r
3739 /* The XSynchronize calls were copied from CreatePieces.
\r
3740 Not sure if needed, but can't hurt */
\r
3741 XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
\r
3743 /* Setup translations so piece colors match square colors */
\r
3744 symbols[0].name = "light_piece";
\r
3745 symbols[0].value = appData.whitePieceColor;
\r
3746 symbols[1].name = "dark_piece";
\r
3747 symbols[1].value = appData.blackPieceColor;
\r
3748 symbols[2].name = "light_square";
\r
3749 symbols[2].value = appData.lightSquareColor;
\r
3750 symbols[3].name = "dark_square";
\r
3751 symbols[3].value = appData.darkSquareColor;
\r
3753 attr.valuemask = XpmColorSymbols;
\r
3754 attr.colorsymbols = symbols;
\r
3755 attr.numsymbols = 4;
\r
3757 if (appData.monoMode) {
\r
3758 DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
\r
3762 if (strlen(appData.pixmapDirectory) == 0) {
\r
3763 XpmPieces* pieces = builtInXpms;
\r
3766 while (pieces->size != squareSize && pieces->size) pieces++;
\r
3767 if (!pieces->size) {
\r
3768 fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
\r
3771 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3772 for (kind=0; kind<4; kind++) {
\r
3774 if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
\r
3775 pieces->xpm[piece][kind],
\r
3776 &(xpmPieceBitmap[kind][piece]),
\r
3777 NULL, &attr)) != 0) {
\r
3778 fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
\r
3785 xpmJailSquare = xpmLightSquare;
\r
3789 fprintf(stderr, _("\nLoading XPMs...\n"));
\r
3792 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3793 fprintf(stderr, "%d ", piece+1);
\r
3794 for (kind=0; kind<4; kind++) {
\r
3795 sprintf(buf, "%s/%c%s%u.xpm",
\r
3796 ExpandPathName(appData.pixmapDirectory),
\r
3797 ToLower(PieceToChar((ChessSquare)piece)),
\r
3798 xpmkind[kind], ss);
\r
3799 if (appData.debugMode) {
\r
3800 fprintf(stderr, _("(File:%s:) "), buf);
\r
3802 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3803 &(xpmPieceBitmap[kind][piece]),
\r
3804 NULL, &attr)) != 0) {
\r
3805 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
\r
3811 /* Load light and dark squares */
\r
3812 /* If the LSQ and DSQ pieces don't exist, we will
\r
3813 draw them with solid squares. */
\r
3814 fprintf(stderr, _("light square "));
\r
3815 sprintf(buf, "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
\r
3816 if (access(buf, 0) != 0) {
\r
3820 if (appData.debugMode)
\r
3821 fprintf(stderr, _("(File:%s:) "), buf);
\r
3823 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3824 &xpmLightSquare, NULL, &attr)) != 0) {
\r
3825 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
\r
3828 fprintf(stderr, _("dark square "));
\r
3829 sprintf(buf, "%s/dsq%u.xpm",
\r
3830 ExpandPathName(appData.pixmapDirectory), ss);
\r
3831 if (appData.debugMode) {
\r
3832 fprintf(stderr, _("(File:%s:) "), buf);
\r
3834 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3835 &xpmDarkSquare, NULL, &attr)) != 0) {
\r
3836 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
\r
3840 xpmJailSquare = xpmLightSquare;
\r
3841 fprintf(stderr, _("Done.\n"));
\r
3843 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3846 #endif /* HAVE_LIBXPM */
\r
3849 /* No built-in bitmaps */
\r
3850 void CreatePieces()
\r
3853 char buf[MSG_SIZ];
\r
3854 u_int ss = squareSize;
\r
3856 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3859 for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
\r
3860 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3861 sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
\r
3862 ss, kind == SOLID ? 's' : 'o');
\r
3863 ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);
\r
3867 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3871 /* With built-in bitmaps */
\r
3872 void CreatePieces()
\r
3874 BuiltInBits* bib = builtInBits;
\r
3876 char buf[MSG_SIZ];
\r
3877 u_int ss = squareSize;
\r
3879 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3882 while (bib->squareSize != ss && bib->squareSize != 0) bib++;
\r
3884 for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
\r
3885 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3886 sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
\r
3887 ss, kind == SOLID ? 's' : 'o');
\r
3888 ReadBitmap(&pieceBitmap[kind][piece], buf,
\r
3889 bib->bits[kind][piece], ss, ss);
\r
3893 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3898 void ReadBitmap(pm, name, bits, wreq, hreq)
\r
3901 unsigned char bits[];
\r
3907 char msg[MSG_SIZ], fullname[MSG_SIZ];
\r
3909 if (*appData.bitmapDirectory != NULLCHAR) {
\r
3910 strcpy(fullname, appData.bitmapDirectory);
\r
3911 strcat(fullname, "/");
\r
3912 strcat(fullname, name);
\r
3913 errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
\r
3914 &w, &h, pm, &x_hot, &y_hot);
\r
3915 if (errcode != BitmapSuccess) {
\r
3916 switch (errcode) {
\r
3917 case BitmapOpenFailed:
\r
3918 sprintf(msg, _("Can't open bitmap file %s"), fullname);
\r
3920 case BitmapFileInvalid:
\r
3921 sprintf(msg, _("Invalid bitmap in file %s"), fullname);
\r
3923 case BitmapNoMemory:
\r
3924 sprintf(msg, _("Ran out of memory reading bitmap file %s"),
\r
3928 sprintf(msg, _("Unknown XReadBitmapFile error %d on file %s"),
\r
3929 errcode, fullname);
\r
3932 fprintf(stderr, _("%s: %s...using built-in\n"),
\r
3933 programName, msg);
\r
3934 } else if (w != wreq || h != hreq) {
\r
3936 _("%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n"),
\r
3937 programName, fullname, w, h, wreq, hreq);
\r
3942 if (bits == NULL) {
\r
3944 fprintf(stderr, _("%s: No built-in bitmap for %s; giving up\n"),
\r
3945 programName, name);
\r
3948 ; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
\r
3950 *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
\r
3959 if (lineGap == 0) return;
\r
3961 /* [HR] Split this into 2 loops for non-square boards. */
\r
3963 for (i = 0; i < BOARD_HEIGHT + 1; i++) {
\r
3964 gridSegments[i].x1 = 0;
\r
3965 gridSegments[i].x2 =
\r
3966 lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
3967 gridSegments[i].y1 = gridSegments[i].y2
\r
3968 = lineGap / 2 + (i * (squareSize + lineGap));
\r
3971 for (j = 0; j < BOARD_WIDTH + 1; j++) {
\r
3972 gridSegments[j + i].y1 = 0;
\r
3973 gridSegments[j + i].y2 =
\r
3974 lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
3975 gridSegments[j + i].x1 = gridSegments[j + i].x2
\r
3976 = lineGap / 2 + (j * (squareSize + lineGap));
\r
3980 static void MenuBarSelect(w, addr, index)
\r
3985 XtActionProc proc = (XtActionProc) addr;
\r
3987 (proc)(NULL, NULL, NULL, NULL);
\r
3990 void CreateMenuBarPopup(parent, name, mb)
\r
3996 Widget menu, entry;
\r
4000 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
\r
4003 XtSetArg(args[j], XtNleftMargin, 20); j++;
\r
4004 XtSetArg(args[j], XtNrightMargin, 20); j++;
\r
4006 while (mi->string != NULL) {
\r
4007 if (strcmp(mi->string, "----") == 0) {
\r
4008 entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
\r
4011 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
\r
4012 entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
\r
4014 XtAddCallback(entry, XtNcallback,
\r
4015 (XtCallbackProc) MenuBarSelect,
\r
4016 (caddr_t) mi->proc);
\r
4022 Widget CreateMenuBar(mb)
\r
4026 Widget anchor, menuBar;
\r
4028 char menuName[MSG_SIZ];
\r
4031 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
\r
4032 XtSetArg(args[j], XtNvSpace, 0); j++;
\r
4033 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4034 menuBar = XtCreateWidget("menuBar", boxWidgetClass,
\r
4035 formWidget, args, j);
\r
4037 while (mb->name != NULL) {
\r
4038 strcpy(menuName, "menu");
\r
4039 strcat(menuName, mb->name);
\r
4041 XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;
\r
4043 char shortName[2];
\r
4044 shortName[0] = _(mb->name)[0];
\r
4045 shortName[1] = NULLCHAR;
\r
4046 XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
\r
4049 XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++;
\r
4052 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4053 anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
\r
4054 menuBar, args, j);
\r
4055 CreateMenuBarPopup(menuBar, menuName, mb);
\r
4061 Widget CreateButtonBar(mi)
\r
4065 Widget button, buttonBar;
\r
4069 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
\r
4071 XtSetArg(args[j], XtNhSpace, 0); j++;
\r
4073 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4074 XtSetArg(args[j], XtNvSpace, 0); j++;
\r
4075 buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
\r
4076 formWidget, args, j);
\r
4078 while (mi->string != NULL) {
\r
4081 XtSetArg(args[j], XtNinternalWidth, 2); j++;
\r
4082 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4084 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
\r
4085 button = XtCreateManagedWidget(mi->string, commandWidgetClass,
\r
4086 buttonBar, args, j);
\r
4087 XtAddCallback(button, XtNcallback,
\r
4088 (XtCallbackProc) MenuBarSelect,
\r
4089 (caddr_t) mi->proc);
\r
4096 CreatePieceMenu(name, color)
\r
4101 Widget entry, menu;
\r
4103 ChessSquare selection;
\r
4105 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
\r
4106 boardWidget, args, 0);
\r
4108 for (i = 0; i < PIECE_MENU_SIZE; i++) {
\r
4109 String item = pieceMenuStrings[color][i];
\r
4111 if (strcmp(item, "----") == 0) {
\r
4112 entry = XtCreateManagedWidget(item, smeLineObjectClass,
\r
4115 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
\r
4116 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
\r
4118 selection = pieceMenuTranslation[color][i];
\r
4119 XtAddCallback(entry, XtNcallback,
\r
4120 (XtCallbackProc) PieceMenuSelect,
\r
4121 (caddr_t) selection);
\r
4122 if (selection == WhitePawn || selection == BlackPawn) {
\r
4123 XtSetArg(args[0], XtNpopupOnEntry, entry);
\r
4124 XtSetValues(menu, args, 1);
\r
4132 CreatePieceMenus()
\r
4137 ChessSquare selection;
\r
4139 whitePieceMenu = CreatePieceMenu("menuW", 0);
\r
4140 blackPieceMenu = CreatePieceMenu("menuB", 1);
\r
4142 XtRegisterGrabAction(PieceMenuPopup, True,
\r
4143 (unsigned)(ButtonPressMask|ButtonReleaseMask),
\r
4144 GrabModeAsync, GrabModeAsync);
\r
4146 XtSetArg(args[0], XtNlabel, _("Drop"));
\r
4147 dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
\r
4148 boardWidget, args, 1);
\r
4149 for (i = 0; i < DROP_MENU_SIZE; i++) {
\r
4150 String item = dropMenuStrings[i];
\r
4152 if (strcmp(item, "----") == 0) {
\r
4153 entry = XtCreateManagedWidget(item, smeLineObjectClass,
\r
4154 dropMenu, NULL, 0);
\r
4156 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
\r
4157 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
\r
4158 dropMenu, args, 1);
\r
4159 selection = dropMenuTranslation[i];
\r
4160 XtAddCallback(entry, XtNcallback,
\r
4161 (XtCallbackProc) DropMenuSelect,
\r
4162 (caddr_t) selection);
\r
4167 void SetupDropMenu()
\r
4175 for (i=0; i<sizeof(dmEnables)/sizeof(DropMenuEnables); i++) {
\r
4176 entry = XtNameToWidget(dropMenu, dmEnables[i].widget);
\r
4177 p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,
\r
4178 dmEnables[i].piece);
\r
4179 XtSetSensitive(entry, p != NULL || !appData.testLegality
\r
4180 /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse
\r
4181 && !appData.icsActive));
\r
4183 while (p && *p++ == dmEnables[i].piece) count++;
\r
4184 sprintf(label, "%s %d", dmEnables[i].widget, count);
\r
4186 XtSetArg(args[j], XtNlabel, label); j++;
\r
4187 XtSetValues(entry, args, j);
\r
4191 void PieceMenuPopup(w, event, params, num_params)
\r
4195 Cardinal *num_params;
\r
4198 if (event->type != ButtonPress) return;
\r
4199 if (errorUp) ErrorPopDown();
\r
4200 switch (gameMode) {
\r
4201 case EditPosition:
\r
4202 case IcsExamining:
\r
4203 whichMenu = params[0];
\r
4205 case IcsPlayingWhite:
\r
4206 case IcsPlayingBlack:
\r
4208 case MachinePlaysWhite:
\r
4209 case MachinePlaysBlack:
\r
4210 if (appData.testLegality &&
\r
4211 gameInfo.variant != VariantBughouse &&
\r
4212 gameInfo.variant != VariantCrazyhouse) return;
\r
4214 whichMenu = "menuD";
\r
4220 if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||
\r
4221 ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {
\r
4222 pmFromX = pmFromY = -1;
\r
4226 pmFromX = BOARD_WIDTH - 1 - pmFromX;
\r
4228 pmFromY = BOARD_HEIGHT - 1 - pmFromY;
\r
4230 XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
\r
4233 static void PieceMenuSelect(w, piece, junk)
\r
4235 ChessSquare piece;
\r
4238 if (pmFromX < 0 || pmFromY < 0) return;
\r
4239 EditPositionMenuEvent(piece, pmFromX, pmFromY);
\r
4242 static void DropMenuSelect(w, piece, junk)
\r
4244 ChessSquare piece;
\r
4247 if (pmFromX < 0 || pmFromY < 0) return;
\r
4248 DropMenuEvent(piece, pmFromX, pmFromY);
\r
4251 void WhiteClock(w, event, prms, nprms)
\r
4257 if (gameMode == EditPosition || gameMode == IcsExamining) {
\r
4258 SetWhiteToPlayEvent();
\r
4259 } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
\r
4264 void BlackClock(w, event, prms, nprms)
\r
4270 if (gameMode == EditPosition || gameMode == IcsExamining) {
\r
4271 SetBlackToPlayEvent();
\r
4272 } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
\r
4279 * If the user selects on a border boundary, return -1; if off the board,
\r
4280 * return -2. Otherwise map the event coordinate to the square.
\r
4282 int EventToSquare(x, limit)
\r
4290 if ((x % (squareSize + lineGap)) >= squareSize)
\r
4292 x /= (squareSize + lineGap);
\r
4298 static void do_flash_delay(msec)
\r
4299 unsigned long msec;
\r
4304 static void drawHighlight(file, rank, gc)
\r
4310 if (lineGap == 0 || appData.blindfold) return;
\r
4313 x = lineGap/2 + ((BOARD_WIDTH-1)-file) *
\r
4314 (squareSize + lineGap);
\r
4315 y = lineGap/2 + rank * (squareSize + lineGap);
\r
4317 x = lineGap/2 + file * (squareSize + lineGap);
\r
4318 y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) *
\r
4319 (squareSize + lineGap);
\r
4322 XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
\r
4323 squareSize+lineGap, squareSize+lineGap);
\r
4326 int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
\r
4327 int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1;
\r
4330 SetHighlights(fromX, fromY, toX, toY)
\r
4331 int fromX, fromY, toX, toY;
\r
4333 if (hi1X != fromX || hi1Y != fromY) {
\r
4334 if (hi1X >= 0 && hi1Y >= 0) {
\r
4335 drawHighlight(hi1X, hi1Y, lineGC);
\r
4337 if (fromX >= 0 && fromY >= 0) {
\r
4338 drawHighlight(fromX, fromY, highlineGC);
\r
4341 if (hi2X != toX || hi2Y != toY) {
\r
4342 if (hi2X >= 0 && hi2Y >= 0) {
\r
4343 drawHighlight(hi2X, hi2Y, lineGC);
\r
4345 if (toX >= 0 && toY >= 0) {
\r
4346 drawHighlight(toX, toY, highlineGC);
\r
4358 SetHighlights(-1, -1, -1, -1);
\r
4363 SetPremoveHighlights(fromX, fromY, toX, toY)
\r
4364 int fromX, fromY, toX, toY;
\r
4366 if (pm1X != fromX || pm1Y != fromY) {
\r
4367 if (pm1X >= 0 && pm1Y >= 0) {
\r
4368 drawHighlight(pm1X, pm1Y, lineGC);
\r
4370 if (fromX >= 0 && fromY >= 0) {
\r
4371 drawHighlight(fromX, fromY, prelineGC);
\r
4374 if (pm2X != toX || pm2Y != toY) {
\r
4375 if (pm2X >= 0 && pm2Y >= 0) {
\r
4376 drawHighlight(pm2X, pm2Y, lineGC);
\r
4378 if (toX >= 0 && toY >= 0) {
\r
4379 drawHighlight(toX, toY, prelineGC);
\r
4389 ClearPremoveHighlights()
\r
4391 SetPremoveHighlights(-1, -1, -1, -1);
\r
4394 static void BlankSquare(x, y, color, piece, dest)
\r
4396 ChessSquare piece;
\r
4399 if (useImages && useImageSqs) {
\r
4402 case 1: /* light */
\r
4403 pm = xpmLightSquare;
\r
4405 case 0: /* dark */
\r
4406 pm = xpmDarkSquare;
\r
4408 case 2: /* neutral */
\r
4410 pm = xpmJailSquare;
\r
4413 XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
\r
4414 squareSize, squareSize, x, y);
\r
4418 case 1: /* light */
\r
4419 gc = lightSquareGC;
\r
4421 case 0: /* dark */
\r
4422 gc = darkSquareGC;
\r
4424 case 2: /* neutral */
\r
4426 gc = jailSquareGC;
\r
4429 XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize);
\r
4434 I split out the routines to draw a piece so that I could
\r
4435 make a generic flash routine.
\r
4437 static void monoDrawPiece_1bit(piece, square_color, x, y, dest)
\r
4438 ChessSquare piece;
\r
4439 int square_color, x, y;
\r
4442 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
\r
4443 switch (square_color) {
\r
4444 case 1: /* light */
\r
4445 case 2: /* neutral */
\r
4447 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
\r
4448 ? *pieceToOutline(piece)
\r
4449 : *pieceToSolid(piece),
\r
4450 dest, bwPieceGC, 0, 0,
\r
4451 squareSize, squareSize, x, y);
\r
4453 case 0: /* dark */
\r
4454 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
\r
4455 ? *pieceToSolid(piece)
\r
4456 : *pieceToOutline(piece),
\r
4457 dest, wbPieceGC, 0, 0,
\r
4458 squareSize, squareSize, x, y);
\r
4463 static void monoDrawPiece(piece, square_color, x, y, dest)
\r
4464 ChessSquare piece;
\r
4465 int square_color, x, y;
\r
4468 switch (square_color) {
\r
4469 case 1: /* light */
\r
4470 case 2: /* neutral */
\r
4472 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
\r
4473 ? *pieceToOutline(piece)
\r
4474 : *pieceToSolid(piece),
\r
4475 dest, bwPieceGC, 0, 0,
\r
4476 squareSize, squareSize, x, y, 1);
\r
4478 case 0: /* dark */
\r
4479 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
\r
4480 ? *pieceToSolid(piece)
\r
4481 : *pieceToOutline(piece),
\r
4482 dest, wbPieceGC, 0, 0,
\r
4483 squareSize, squareSize, x, y, 1);
\r
4488 static void colorDrawPiece(piece, square_color, x, y, dest)
\r
4489 ChessSquare piece;
\r
4490 int square_color, x, y;
\r
4493 if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
\r
4494 switch (square_color) {
\r
4495 case 1: /* light */
\r
4496 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4497 dest, (int) piece < (int) BlackPawn
\r
4498 ? wlPieceGC : blPieceGC, 0, 0,
\r
4499 squareSize, squareSize, x, y, 1);
\r
4501 case 0: /* dark */
\r
4502 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4503 dest, (int) piece < (int) BlackPawn
\r
4504 ? wdPieceGC : bdPieceGC, 0, 0,
\r
4505 squareSize, squareSize, x, y, 1);
\r
4507 case 2: /* neutral */
\r
4509 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4510 dest, (int) piece < (int) BlackPawn
\r
4511 ? wjPieceGC : bjPieceGC, 0, 0,
\r
4512 squareSize, squareSize, x, y, 1);
\r
4517 static void colorDrawPieceImage(piece, square_color, x, y, dest)
\r
4518 ChessSquare piece;
\r
4519 int square_color, x, y;
\r
4524 switch (square_color) {
\r
4525 case 1: /* light */
\r
4526 case 2: /* neutral */
\r
4528 if ((int)piece < (int) BlackPawn) {
\r
4532 piece -= BlackPawn;
\r
4535 case 0: /* dark */
\r
4536 if ((int)piece < (int) BlackPawn) {
\r
4540 piece -= BlackPawn;
\r
4544 XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
\r
4545 dest, wlPieceGC, 0, 0,
\r
4546 squareSize, squareSize, x, y);
\r
4549 typedef void (*DrawFunc)();
\r
4551 DrawFunc ChooseDrawFunc()
\r
4553 if (appData.monoMode) {
\r
4554 if (DefaultDepth(xDisplay, xScreen) == 1) {
\r
4555 return monoDrawPiece_1bit;
\r
4557 return monoDrawPiece;
\r
4561 return colorDrawPieceImage;
\r
4563 return colorDrawPiece;
\r
4567 /* [HR] determine square color depending on chess variant. */
\r
4568 static int SquareColor(row, column)
\r
4573 if (gameInfo.variant == VariantXiangqi) {
\r
4574 if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {
\r
4576 } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {
\r
4578 } else if (row <= 4) {
\r
4584 square_color = ((column + row) % 2) == 1;
\r
4587 /* [hgm] holdings: next line makes all holdings squares light */
\r
4588 if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1;
\r
4590 return square_color;
\r
4593 void DrawSquare(row, column, piece, do_flash)
\r
4594 int row, column, do_flash;
\r
4595 ChessSquare piece;
\r
4597 int square_color, x, y, direction, font_ascent, font_descent;
\r
4600 XCharStruct overall;
\r
4601 DrawFunc drawfunc;
\r
4604 if(gameInfo.variant == VariantShogi) { // [HGM] shogi: in shogi Q is used for Lance
\r
4605 if(piece == WhiteQueen) piece = WhiteLance; else
\r
4606 if(piece == BlackQueen) piece = BlackLance;
\r
4609 else if(gameInfo.variant == VariantGothic) { // [HGM] shogi: in Gothic Chancelor has alternative look
\r
4610 if(piece == WhiteMarshall) piece = WhiteSilver; else
\r
4611 if(piece == BlackMarshall) piece = BlackSilver;
\r
4615 /* Calculate delay in milliseconds (2-delays per complete flash) */
\r
4616 flash_delay = 500 / appData.flashRate;
\r
4619 x = lineGap + ((BOARD_WIDTH-1)-column) *
\r
4620 (squareSize + lineGap);
\r
4621 y = lineGap + row * (squareSize + lineGap);
\r
4623 x = lineGap + column * (squareSize + lineGap);
\r
4624 y = lineGap + ((BOARD_HEIGHT-1)-row) *
\r
4625 (squareSize + lineGap);
\r
4628 square_color = SquareColor(row, column);
\r
4630 if ( // [HGM] holdings: blank out area between board and holdings
\r
4631 column == BOARD_LEFT-1 || column == BOARD_RGHT
\r
4632 || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)
\r
4633 || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {
\r
4634 BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
\r
4636 // [HGM] print piece counts next to holdings
\r
4637 string[1] = NULLCHAR;
\r
4638 if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) {
\r
4639 string[0] = '0' + piece;
\r
4640 XTextExtents(countFontStruct, string, 1, &direction,
\r
4641 &font_ascent, &font_descent, &overall);
\r
4642 if (appData.monoMode) {
\r
4643 XDrawImageString(xDisplay, xBoardWindow, countGC,
\r
4644 x + squareSize - overall.width - 2,
\r
4645 y + font_ascent + 1, string, 1);
\r
4647 XDrawString(xDisplay, xBoardWindow, countGC,
\r
4648 x + squareSize - overall.width - 2,
\r
4649 y + font_ascent + 1, string, 1);
\r
4652 if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) {
\r
4653 string[0] = '0' + piece;
\r
4654 XTextExtents(countFontStruct, string, 1, &direction,
\r
4655 &font_ascent, &font_descent, &overall);
\r
4656 if (appData.monoMode) {
\r
4657 XDrawImageString(xDisplay, xBoardWindow, countGC,
\r
4658 x + 2, y + font_ascent + 1, string, 1);
\r
4660 XDrawString(xDisplay, xBoardWindow, countGC,
\r
4661 x + 2, y + font_ascent + 1, string, 1);
\r
4665 if (piece == EmptySquare || appData.blindfold) {
\r
4666 BlankSquare(x, y, square_color, piece, xBoardWindow);
\r
4668 drawfunc = ChooseDrawFunc();
\r
4669 if (do_flash && appData.flashCount > 0) {
\r
4670 for (i=0; i<appData.flashCount; ++i) {
\r
4672 drawfunc(piece, square_color, x, y, xBoardWindow);
\r
4673 XSync(xDisplay, False);
\r
4674 do_flash_delay(flash_delay);
\r
4676 BlankSquare(x, y, square_color, piece, xBoardWindow);
\r
4677 XSync(xDisplay, False);
\r
4678 do_flash_delay(flash_delay);
\r
4681 drawfunc(piece, square_color, x, y, xBoardWindow);
\r
4685 string[1] = NULLCHAR;
\r
4686 if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)
\r
4687 && column >= BOARD_LEFT && column < BOARD_RGHT) {
\r
4688 string[0] = 'a' + column - BOARD_LEFT;
\r
4689 XTextExtents(coordFontStruct, string, 1, &direction,
\r
4690 &font_ascent, &font_descent, &overall);
\r
4691 if (appData.monoMode) {
\r
4692 XDrawImageString(xDisplay, xBoardWindow, coordGC,
\r
4693 x + squareSize - overall.width - 2,
\r
4694 y + squareSize - font_descent - 1, string, 1);
\r
4696 XDrawString(xDisplay, xBoardWindow, coordGC,
\r
4697 x + squareSize - overall.width - 2,
\r
4698 y + squareSize - font_descent - 1, string, 1);
\r
4701 if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) {
\r
4702 string[0] = ONE + row;
\r
4703 XTextExtents(coordFontStruct, string, 1, &direction,
\r
4704 &font_ascent, &font_descent, &overall);
\r
4705 if (appData.monoMode) {
\r
4706 XDrawImageString(xDisplay, xBoardWindow, coordGC,
\r
4707 x + 2, y + font_ascent + 1, string, 1);
\r
4709 XDrawString(xDisplay, xBoardWindow, coordGC,
\r
4710 x + 2, y + font_ascent + 1, string, 1);
\r
4716 /* Why is this needed on some versions of X? */
\r
4717 void EventProc(widget, unused, event)
\r
4722 if (!XtIsRealized(widget))
\r
4725 switch (event->type) {
\r
4727 if (event->xexpose.count > 0) return; /* no clipping is done */
\r
4728 XDrawPosition(widget, True, NULL);
\r
4736 void DrawPosition(fullRedraw, board)
\r
4737 /*Boolean*/int fullRedraw;
\r
4740 XDrawPosition(boardWidget, fullRedraw, board);
\r
4743 /* Returns 1 if there are "too many" differences between b1 and b2
\r
4744 (i.e. more than 1 move was made) */
\r
4745 static int too_many_diffs(b1, b2)
\r
4751 for (i=0; i<BOARD_HEIGHT; ++i) {
\r
4752 for (j=0; j<BOARD_WIDTH; ++j) {
\r
4753 if (b1[i][j] != b2[i][j]) {
\r
4754 if (++c > 4) /* Castling causes 4 diffs */
\r
4763 /* Matrix describing castling maneuvers */
\r
4764 /* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */
\r
4765 static int castling_matrix[4][5] = {
\r
4766 { 0, 0, 4, 3, 2 }, /* 0-0-0, white */
\r
4767 { 0, 7, 4, 5, 6 }, /* 0-0, white */
\r
4768 { 7, 0, 4, 3, 2 }, /* 0-0-0, black */
\r
4769 { 7, 7, 4, 5, 6 } /* 0-0, black */
\r
4772 /* Checks whether castling occurred. If it did, *rrow and *rcol
\r
4773 are set to the destination (row,col) of the rook that moved.
\r
4775 Returns 1 if castling occurred, 0 if not.
\r
4777 Note: Only handles a max of 1 castling move, so be sure
\r
4778 to call too_many_diffs() first.
\r
4780 static int check_castle_draw(newb, oldb, rrow, rcol)
\r
4787 /* For each type of castling... */
\r
4788 for (i=0; i<4; ++i) {
\r
4789 r = castling_matrix[i];
\r
4791 /* Check the 4 squares involved in the castling move */
\r
4793 for (j=1; j<=4; ++j) {
\r
4794 if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) {
\r
4801 /* All 4 changed, so it must be a castling move */
\r
4810 static int damage[BOARD_SIZE][BOARD_SIZE];
\r
4813 * event handler for redrawing the board
\r
4815 void XDrawPosition(w, repaint, board)
\r
4817 /*Boolean*/int repaint;
\r
4820 int i, j, do_flash;
\r
4821 static int lastFlipView = 0;
\r
4822 static int lastBoardValid = 0;
\r
4823 static Board lastBoard;
\r
4827 if (board == NULL) {
\r
4828 if (!lastBoardValid) return;
\r
4829 board = lastBoard;
\r
4831 if (!lastBoardValid || lastFlipView != flipView) {
\r
4832 XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
\r
4833 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
\r
4838 * It would be simpler to clear the window with XClearWindow()
\r
4839 * but this causes a very distracting flicker.
\r
4842 if (!repaint && lastBoardValid && lastFlipView == flipView) {
\r
4844 /* If too much changes (begin observing new game, etc.), don't
\r
4846 do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
\r
4848 /* Special check for castling so we don't flash both the king
\r
4849 and the rook (just flash the king). */
\r
4851 if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
\r
4852 /* Draw rook with NO flashing. King will be drawn flashing later */
\r
4853 DrawSquare(rrow, rcol, board[rrow][rcol], 0);
\r
4854 lastBoard[rrow][rcol] = board[rrow][rcol];
\r
4858 /* First pass -- Draw (newly) empty squares and repair damage.
\r
4859 This prevents you from having a piece show up twice while it
\r
4860 is flashing on its new square */
\r
4861 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4862 for (j = 0; j < BOARD_WIDTH; j++)
\r
4863 if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
\r
4864 || damage[i][j]) {
\r
4865 DrawSquare(i, j, board[i][j], 0);
\r
4866 damage[i][j] = False;
\r
4869 /* Second pass -- Draw piece(s) in new position and flash them */
\r
4870 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4871 for (j = 0; j < BOARD_WIDTH; j++)
\r
4872 if (board[i][j] != lastBoard[i][j]) {
\r
4873 DrawSquare(i, j, board[i][j], do_flash);
\r
4877 XDrawSegments(xDisplay, xBoardWindow, lineGC,
\r
4878 gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
\r
4880 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4881 for (j = 0; j < BOARD_WIDTH; j++) {
\r
4882 DrawSquare(i, j, board[i][j], 0);
\r
4883 damage[i][j] = False;
\r
4887 CopyBoard(lastBoard, board);
\r
4888 lastBoardValid = 1;
\r
4889 lastFlipView = flipView;
\r
4891 /* Draw highlights */
\r
4892 if (pm1X >= 0 && pm1Y >= 0) {
\r
4893 drawHighlight(pm1X, pm1Y, prelineGC);
\r
4895 if (pm2X >= 0 && pm2Y >= 0) {
\r
4896 drawHighlight(pm2X, pm2Y, prelineGC);
\r
4898 if (hi1X >= 0 && hi1Y >= 0) {
\r
4899 drawHighlight(hi1X, hi1Y, highlineGC);
\r
4901 if (hi2X >= 0 && hi2Y >= 0) {
\r
4902 drawHighlight(hi2X, hi2Y, highlineGC);
\r
4905 /* If piece being dragged around board, must redraw that too */
\r
4908 XSync(xDisplay, False);
\r
4913 * event handler for redrawing the board
\r
4915 void DrawPositionProc(w, event, prms, nprms)
\r
4921 XDrawPosition(w, True, NULL);
\r
4926 * event handler for parsing user moves
\r
4928 // [HGM] This routine will need quite some reworking. Although the backend still supports the old
\r
4929 // way of doing things, by calling UserMoveEvent() to test the legality of the move and then perform
\r
4930 // it at the end, and doing all kind of preliminary tests here (e.g. to weed out self-captures), it
\r
4931 // should be made to use the new way, of calling UserMoveTest early to determine the legality of the
\r
4932 // move, (which will weed out the illegal selfcaptures and moves into the holdings, and flag promotions),
\r
4933 // and at the end FinishMove() to perform the move after optional promotion popups.
\r
4934 // For now I patched it to allow self-capture with King, and suppress clicks between board and holdings.
\r
4935 void HandleUserMove(w, event, prms, nprms)
\r
4942 Boolean saveAnimate;
\r
4943 static int second = 0;
\r
4945 if (w != boardWidget || errorExitStatus != -1) return;
\r
4947 if (event->type == ButtonPress) ErrorPopDown();
\r
4949 if (promotionUp) {
\r
4950 if (event->type == ButtonPress) {
\r
4951 XtPopdown(promotionShell);
\r
4952 XtDestroyWidget(promotionShell);
\r
4953 promotionUp = False;
\r
4954 ClearHighlights();
\r
4955 fromX = fromY = -1;
\r
4961 x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
\r
4962 y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
\r
4963 if (!flipView && y >= 0) {
\r
4964 y = BOARD_HEIGHT - 1 - y;
\r
4966 if (flipView && x >= 0) {
\r
4967 x = BOARD_WIDTH - 1 - x;
\r
4970 /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
\r
4971 if(event->type == ButtonPress
\r
4972 && ( x == BOARD_LEFT-1 || x == BOARD_RGHT
\r
4973 || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize
\r
4974 || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) )
\r
4977 if (fromX == -1) {
\r
4978 if (event->type == ButtonPress) {
\r
4979 /* First square */
\r
4980 if (OKToStartUserMove(x, y)) {
\r
4984 DragPieceBegin(event->xbutton.x, event->xbutton.y);
\r
4985 if (appData.highlightDragging) {
\r
4986 SetHighlights(x, y, -1, -1);
\r
4994 if (event->type == ButtonPress && gameMode != EditPosition &&
\r
4995 x >= 0 && y >= 0) {
\r
4996 ChessSquare fromP;
\r
4999 /* Check if clicking again on the same color piece */
\r
5000 fromP = boards[currentMove][fromY][fromX];
\r
5001 toP = boards[currentMove][y][x];
\r
5002 if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.
\r
5003 WhitePawn <= toP && toP <= WhiteKing) || // For now I made it less critical by exempting King
\r
5004 (BlackPawn <= fromP && fromP < BlackKing && // moves, to not interfere with FRC castlings.
\r
5005 BlackPawn <= toP && toP <= BlackKing)) {
\r
5006 /* Clicked again on same color piece -- changed his mind */
\r
5007 second = (x == fromX && y == fromY);
\r
5008 if (appData.highlightDragging) {
\r
5009 SetHighlights(x, y, -1, -1);
\r
5011 ClearHighlights();
\r
5013 if (OKToStartUserMove(x, y)) {
\r
5016 DragPieceBegin(event->xbutton.x, event->xbutton.y);
\r
5022 if (event->type == ButtonRelease && x == fromX && y == fromY) {
\r
5023 DragPieceEnd(event->xbutton.x, event->xbutton.y);
\r
5024 if (appData.animateDragging) {
\r
5025 /* Undo animation damage if any */
\r
5026 DrawPosition(FALSE, NULL);
\r
5029 /* Second up/down in same square; just abort move */
\r
5031 fromX = fromY = -1;
\r
5032 ClearHighlights();
\r
5034 ClearPremoveHighlights();
\r
5036 /* First upclick in same square; start click-click mode */
\r
5037 SetHighlights(x, y, -1, -1);
\r
5042 /* Completed move */
\r
5045 saveAnimate = appData.animate;
\r
5046 if (event->type == ButtonPress) {
\r
5047 /* Finish clickclick move */
\r
5048 if (appData.animate || appData.highlightLastMove) {
\r
5049 SetHighlights(fromX, fromY, toX, toY);
\r
5051 ClearHighlights();
\r
5054 /* Finish drag move */
\r
5055 if (appData.highlightLastMove) {
\r
5056 SetHighlights(fromX, fromY, toX, toY);
\r
5058 ClearHighlights();
\r
5060 DragPieceEnd(event->xbutton.x, event->xbutton.y);
\r
5061 /* Don't animate move and drag both */
\r
5062 appData.animate = FALSE;
\r
5064 if (IsPromotion(fromX, fromY, toX, toY)) {
\r
5065 if (appData.alwaysPromoteToQueen) {
\r
5066 UserMoveEvent(fromX, fromY, toX, toY, 'q');
\r
5067 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5068 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5069 fromX = fromY = -1;
\r
5071 SetHighlights(fromX, fromY, toX, toY);
\r
5075 UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
\r
5076 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5077 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5078 fromX = fromY = -1;
\r
5080 appData.animate = saveAnimate;
\r
5081 if (appData.animate || appData.animateDragging) {
\r
5082 /* Undo animation damage if needed */
\r
5083 DrawPosition(FALSE, NULL);
\r
5087 void AnimateUserMove (Widget w, XEvent * event,
\r
5088 String * params, Cardinal * nParams)
\r
5090 DragPieceMove(event->xmotion.x, event->xmotion.y);
\r
5093 Widget CommentCreate(name, text, mutable, callback, lines)
\r
5094 char *name, *text;
\r
5095 int /*Boolean*/ mutable;
\r
5096 XtCallbackProc callback;
\r
5100 Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
\r
5101 Dimension bw_width;
\r
5105 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5106 XtGetValues(boardWidget, args, j);
\r
5109 XtSetArg(args[j], XtNresizable, True); j++;
\r
5112 XtCreatePopupShell(name, topLevelShellWidgetClass,
\r
5113 shellWidget, args, j);
\r
5116 XtCreatePopupShell(name, transientShellWidgetClass,
\r
5117 shellWidget, args, j);
\r
5120 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
\r
5121 layoutArgs, XtNumber(layoutArgs));
\r
5123 XtCreateManagedWidget("form", formWidgetClass, layout,
\r
5124 formArgs, XtNumber(formArgs));
\r
5128 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
\r
5129 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
\r
5131 XtSetArg(args[j], XtNstring, text); j++;
\r
5132 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
5133 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5134 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5135 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
5136 XtSetArg(args[j], XtNresizable, True); j++;
\r
5137 XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/
\r
5139 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
\r
5141 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
\r
5142 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
\r
5144 XtSetArg(args[j], XtNautoFill, True); j++;
\r
5145 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
\r
5147 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
\r
5151 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5152 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5153 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5154 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5155 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5157 XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j);
\r
5158 XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
\r
5161 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5162 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
\r
5163 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5164 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5165 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5166 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5168 XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
\r
5169 XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
\r
5172 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5173 XtSetArg(args[j], XtNfromHoriz, b_cancel); 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(_("clear"), commandWidgetClass, form, args, j);
\r
5180 XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
\r
5183 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5184 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5185 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5186 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5187 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5189 XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j);
\r
5190 XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
\r
5193 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5194 XtSetArg(args[j], XtNfromHoriz, b_close); j++;
\r
5195 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5196 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5197 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5198 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5200 XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j);
\r
5201 XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
\r
5204 XtRealizeWidget(shell);
\r
5206 if (commentX == -1) {
\r
5209 Dimension pw_height;
\r
5210 Dimension ew_height;
\r
5213 XtSetArg(args[j], XtNheight, &ew_height); j++;
\r
5214 XtGetValues(edit, args, j);
\r
5217 XtSetArg(args[j], XtNheight, &pw_height); j++;
\r
5218 XtGetValues(shell, args, j);
\r
5219 commentH = pw_height + (lines - 1) * ew_height;
\r
5220 commentW = bw_width - 16;
\r
5222 XSync(xDisplay, False);
\r
5224 /* This code seems to tickle an X bug if it is executed too soon
\r
5225 after xboard starts up. The coordinates get transformed as if
\r
5226 the main window was positioned at (0, 0).
\r
5228 XtTranslateCoords(shellWidget,
\r
5229 (bw_width - commentW) / 2, 0 - commentH / 2,
\r
5230 &commentX, &commentY);
\r
5232 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
\r
5233 RootWindowOfScreen(XtScreen(shellWidget)),
\r
5234 (bw_width - commentW) / 2, 0 - commentH / 2,
\r
5238 #endif /*!NOTDEF*/
\r
5239 if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/
\r
5242 XtSetArg(args[j], XtNheight, commentH); j++;
\r
5243 XtSetArg(args[j], XtNwidth, commentW); j++;
\r
5244 XtSetArg(args[j], XtNx, commentX); j++;
\r
5245 XtSetArg(args[j], XtNy, commentY); j++;
\r
5246 XtSetValues(shell, args, j);
\r
5247 XtSetKeyboardFocus(shell, edit);
\r
5252 /* Used for analysis window and ICS input window */
\r
5253 Widget MiscCreate(name, text, mutable, callback, lines)
\r
5254 char *name, *text;
\r
5255 int /*Boolean*/ mutable;
\r
5256 XtCallbackProc callback;
\r
5260 Widget shell, layout, form, edit;
\r
5262 Dimension bw_width, pw_height, ew_height, w, h;
\r
5268 XtSetArg(args[j], XtNresizable, True); j++;
\r
5271 XtCreatePopupShell(name, topLevelShellWidgetClass,
\r
5272 shellWidget, args, j);
\r
5275 XtCreatePopupShell(name, transientShellWidgetClass,
\r
5276 shellWidget, args, j);
\r
5279 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
\r
5280 layoutArgs, XtNumber(layoutArgs));
\r
5282 XtCreateManagedWidget("form", formWidgetClass, layout,
\r
5283 formArgs, XtNumber(formArgs));
\r
5287 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
\r
5288 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
\r
5290 XtSetArg(args[j], XtNstring, text); j++;
\r
5291 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
5292 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5293 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5294 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
5295 XtSetArg(args[j], XtNresizable, True); j++;
\r
5297 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
\r
5299 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
\r
5300 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
\r
5302 XtSetArg(args[j], XtNautoFill, True); j++;
\r
5303 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
\r
5305 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
\r
5307 XtRealizeWidget(shell);
\r
5310 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5311 XtGetValues(boardWidget, args, j);
\r
5314 XtSetArg(args[j], XtNheight, &ew_height); j++;
\r
5315 XtGetValues(edit, args, j);
\r
5318 XtSetArg(args[j], XtNheight, &pw_height); j++;
\r
5319 XtGetValues(shell, args, j);
\r
5320 h = pw_height + (lines - 1) * ew_height;
\r
5321 w = bw_width - 16;
\r
5323 XSync(xDisplay, False);
\r
5325 /* This code seems to tickle an X bug if it is executed too soon
\r
5326 after xboard starts up. The coordinates get transformed as if
\r
5327 the main window was positioned at (0, 0).
\r
5329 XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);
\r
5331 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
\r
5332 RootWindowOfScreen(XtScreen(shellWidget)),
\r
5333 (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
\r
5334 #endif /*!NOTDEF*/
\r
5337 if (y < 0) y = 0; /*avoid positioning top offscreen*/
\r
5340 XtSetArg(args[j], XtNheight, h); j++;
\r
5341 XtSetArg(args[j], XtNwidth, w); j++;
\r
5342 XtSetArg(args[j], XtNx, x); j++;
\r
5343 XtSetArg(args[j], XtNy, y); j++;
\r
5344 XtSetValues(shell, args, j);
\r
5350 static int savedIndex; /* gross that this is global */
\r
5352 void EditCommentPopUp(index, title, text)
\r
5354 char *title, *text;
\r
5360 savedIndex = index;
\r
5361 if (text == NULL) text = "";
\r
5363 if (editShell == NULL) {
\r
5365 CommentCreate(title, text, True, EditCommentCallback, 4);
\r
5366 XtRealizeWidget(editShell);
\r
5367 CatchDeleteWindow(editShell, "EditCommentPopDown");
\r
5369 edit = XtNameToWidget(editShell, "*form.text");
\r
5371 XtSetArg(args[j], XtNstring, text); j++;
\r
5372 XtSetValues(edit, args, j);
\r
5374 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5375 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5376 XtSetValues(editShell, args, j);
\r
5379 XtPopup(editShell, XtGrabNone);
\r
5383 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
5384 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
\r
5388 void EditCommentCallback(w, client_data, call_data)
\r
5390 XtPointer client_data, call_data;
\r
5398 XtSetArg(args[j], XtNlabel, &name); j++;
\r
5399 XtGetValues(w, args, j);
\r
5401 if (strcmp(name, _("ok")) == 0) {
\r
5402 edit = XtNameToWidget(editShell, "*form.text");
\r
5404 XtSetArg(args[j], XtNstring, &val); j++;
\r
5405 XtGetValues(edit, args, j);
\r
5406 ReplaceComment(savedIndex, val);
\r
5407 EditCommentPopDown();
\r
5408 } else if (strcmp(name, _("cancel")) == 0) {
\r
5409 EditCommentPopDown();
\r
5410 } else if (strcmp(name, _("clear")) == 0) {
\r
5411 edit = XtNameToWidget(editShell, "*form.text");
\r
5412 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
\r
5413 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
\r
5417 void EditCommentPopDown()
\r
5422 if (!editUp) return;
\r
5424 XtSetArg(args[j], XtNx, &commentX); j++;
\r
5425 XtSetArg(args[j], XtNy, &commentY); j++;
\r
5426 XtSetArg(args[j], XtNheight, &commentH); j++;
\r
5427 XtSetArg(args[j], XtNwidth, &commentW); j++;
\r
5428 XtGetValues(editShell, args, j);
\r
5429 XtPopdown(editShell);
\r
5432 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
5433 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
\r
5437 void ICSInputBoxPopUp()
\r
5442 char *title = _("ICS Input");
\r
5443 XtTranslations tr;
\r
5445 if (ICSInputShell == NULL) {
\r
5446 ICSInputShell = MiscCreate(title, "", True, NULL, 1);
\r
5447 tr = XtParseTranslationTable(ICSInputTranslations);
\r
5448 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5449 XtOverrideTranslations(edit, tr);
\r
5450 XtRealizeWidget(ICSInputShell);
\r
5451 CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
\r
5454 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5456 XtSetArg(args[j], XtNstring, ""); j++;
\r
5457 XtSetValues(edit, args, j);
\r
5459 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5460 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5461 XtSetValues(ICSInputShell, args, j);
\r
5464 XtPopup(ICSInputShell, XtGrabNone);
\r
5465 XtSetKeyboardFocus(ICSInputShell, edit);
\r
5467 ICSInputBoxUp = True;
\r
5469 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
5470 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
\r
5474 void ICSInputSendText()
\r
5481 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5483 XtSetArg(args[j], XtNstring, &val); j++;
\r
5484 XtGetValues(edit, args, j);
\r
5485 SendMultiLineToICS(val);
\r
5486 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
\r
5487 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
\r
5490 void ICSInputBoxPopDown()
\r
5495 if (!ICSInputBoxUp) return;
\r
5497 XtPopdown(ICSInputShell);
\r
5498 ICSInputBoxUp = False;
\r
5500 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
5501 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
\r
5505 void CommentPopUp(title, text)
\r
5506 char *title, *text;
\r
5512 if (commentShell == NULL) {
\r
5514 CommentCreate(title, text, False, CommentCallback, 4);
\r
5515 XtRealizeWidget(commentShell);
\r
5516 CatchDeleteWindow(commentShell, "CommentPopDown");
\r
5518 edit = XtNameToWidget(commentShell, "*form.text");
\r
5520 XtSetArg(args[j], XtNstring, text); j++;
\r
5521 XtSetValues(edit, args, j);
\r
5523 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5524 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5525 XtSetValues(commentShell, args, j);
\r
5528 XtPopup(commentShell, XtGrabNone);
\r
5529 XSync(xDisplay, False);
\r
5534 void AnalysisPopUp(title, text)
\r
5535 char *title, *text;
\r
5541 if (analysisShell == NULL) {
\r
5542 analysisShell = MiscCreate(title, text, False, NULL, 4);
\r
5543 XtRealizeWidget(analysisShell);
\r
5544 CatchDeleteWindow(analysisShell, "AnalysisPopDown");
\r
5547 edit = XtNameToWidget(analysisShell, "*form.text");
\r
5549 XtSetArg(args[j], XtNstring, text); j++;
\r
5550 XtSetValues(edit, args, j);
\r
5552 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5553 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5554 XtSetValues(analysisShell, args, j);
\r
5557 if (!analysisUp) {
\r
5558 XtPopup(analysisShell, XtGrabNone);
\r
5560 XSync(xDisplay, False);
\r
5562 analysisUp = True;
\r
5565 void CommentCallback(w, client_data, call_data)
\r
5567 XtPointer client_data, call_data;
\r
5574 XtSetArg(args[j], XtNlabel, &name); j++;
\r
5575 XtGetValues(w, args, j);
\r
5577 if (strcmp(name, _("close")) == 0) {
\r
5579 } else if (strcmp(name, _("edit")) == 0) {
\r
5581 EditCommentEvent();
\r
5586 void CommentPopDown()
\r
5591 if (!commentUp) return;
\r
5593 XtSetArg(args[j], XtNx, &commentX); j++;
\r
5594 XtSetArg(args[j], XtNy, &commentY); j++;
\r
5595 XtSetArg(args[j], XtNwidth, &commentW); j++;
\r
5596 XtSetArg(args[j], XtNheight, &commentH); j++;
\r
5597 XtGetValues(commentShell, args, j);
\r
5598 XtPopdown(commentShell);
\r
5599 XSync(xDisplay, False);
\r
5600 commentUp = False;
\r
5603 void AnalysisPopDown()
\r
5605 if (!analysisUp) return;
\r
5606 XtPopdown(analysisShell);
\r
5607 XSync(xDisplay, False);
\r
5608 analysisUp = False;
\r
5609 if (appData.icsEngineAnalyze) ExitAnalyzeMode(); /* [DM] icsEngineAnalyze */
\r
5613 void FileNamePopUp(label, def, proc, openMode)
\r
5620 Widget popup, layout, dialog, edit;
\r
5621 Window root, child;
\r
5624 unsigned int mask;
\r
5626 fileProc = proc; /* I can't see a way not */
\r
5627 fileOpenMode = openMode; /* to use globals here */
\r
5630 XtSetArg(args[i], XtNresizable, True); i++;
\r
5631 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
\r
5632 XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++;
\r
5633 fileNameShell = popup =
\r
5634 XtCreatePopupShell("File name prompt", transientShellWidgetClass,
\r
5635 shellWidget, args, i);
\r
5638 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
\r
5639 layoutArgs, XtNumber(layoutArgs));
\r
5642 XtSetArg(args[i], XtNlabel, label); i++;
\r
5643 XtSetArg(args[i], XtNvalue, def); i++;
\r
5644 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
5645 dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
\r
5648 XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog);
\r
5649 XawDialogAddButton(dialog, _("cancel"), FileNameCallback,
\r
5650 (XtPointer) dialog);
\r
5652 XtRealizeWidget(popup);
\r
5653 CatchDeleteWindow(popup, "FileNamePopDown");
\r
5655 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
\r
5656 &x, &y, &win_x, &win_y, &mask);
\r
5658 XtSetArg(args[0], XtNx, x - 10);
\r
5659 XtSetArg(args[1], XtNy, y - 30);
\r
5660 XtSetValues(popup, args, 2);
\r
5662 XtPopup(popup, XtGrabExclusive);
\r
5663 filenameUp = True;
\r
5665 edit = XtNameToWidget(dialog, "*value");
\r
5666 XtSetKeyboardFocus(popup, edit);
\r
5669 void FileNamePopDown()
\r
5671 if (!filenameUp) return;
\r
5672 XtPopdown(fileNameShell);
\r
5673 XtDestroyWidget(fileNameShell);
\r
5674 filenameUp = False;
\r
5678 void FileNameCallback(w, client_data, call_data)
\r
5680 XtPointer client_data, call_data;
\r
5685 XtSetArg(args[0], XtNlabel, &name);
\r
5686 XtGetValues(w, args, 1);
\r
5688 if (strcmp(name, _("cancel")) == 0) {
\r
5689 FileNamePopDown();
\r
5693 FileNameAction(w, NULL, NULL, NULL);
\r
5696 void FileNameAction(w, event, prms, nprms)
\r
5702 char buf[MSG_SIZ];
\r
5705 char *p, *fullname;
\r
5708 name = XawDialogGetValueString(w = XtParent(w));
\r
5710 if ((name != NULL) && (*name != NULLCHAR)) {
\r
5711 strcpy(buf, name);
\r
5712 XtPopdown(w = XtParent(XtParent(w)));
\r
5713 XtDestroyWidget(w);
\r
5714 filenameUp = False;
\r
5716 p = strrchr(buf, ' ');
\r
5723 fullname = ExpandPathName(buf);
\r
5725 ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
\r
5728 f = fopen(fullname, fileOpenMode);
\r
5730 DisplayError(_("Failed to open file"), errno);
\r
5732 (void) (*fileProc)(f, index, buf);
\r
5739 XtPopdown(w = XtParent(XtParent(w)));
\r
5740 XtDestroyWidget(w);
\r
5741 filenameUp = False;
\r
5745 void PromotionPopUp()
\r
5748 Widget dialog, layout;
\r
5750 Dimension bw_width, pw_width;
\r
5754 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5755 XtGetValues(boardWidget, args, j);
\r
5758 XtSetArg(args[j], XtNresizable, True); j++;
\r
5759 XtSetArg(args[j], XtNtitle, XtNewString(_("Promotion"))); j++;
\r
5761 XtCreatePopupShell("Promotion", transientShellWidgetClass,
\r
5762 shellWidget, args, j);
\r
5764 XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
\r
5765 layoutArgs, XtNumber(layoutArgs));
\r
5768 XtSetArg(args[j], XtNlabel, _("Promote pawn to what?")); j++;
\r
5769 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
5770 dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
\r
5773 XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
\r
5774 (XtPointer) dialog);
\r
5775 XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
\r
5776 (XtPointer) dialog);
\r
5777 XawDialogAddButton(dialog, _("Bishop"), PromotionCallback,
\r
5778 (XtPointer) dialog);
\r
5779 XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
\r
5780 (XtPointer) dialog);
\r
5781 if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
\r
5782 gameInfo.variant == VariantGiveaway) {
\r
5783 XawDialogAddButton(dialog, _("King"), PromotionCallback,
\r
5784 (XtPointer) dialog);
\r
5786 XawDialogAddButton(dialog, _("cancel"), PromotionCallback,
\r
5787 (XtPointer) dialog);
\r
5789 XtRealizeWidget(promotionShell);
\r
5790 CatchDeleteWindow(promotionShell, "PromotionPopDown");
\r
5793 XtSetArg(args[j], XtNwidth, &pw_width); j++;
\r
5794 XtGetValues(promotionShell, args, j);
\r
5796 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
\r
5797 lineGap + squareSize/3 +
\r
5798 ((toY == BOARD_HEIGHT-1) ^ (flipView) ?
\r
5799 0 : 6*(squareSize + lineGap)), &x, &y);
\r
5802 XtSetArg(args[j], XtNx, x); j++;
\r
5803 XtSetArg(args[j], XtNy, y); j++;
\r
5804 XtSetValues(promotionShell, args, j);
\r
5806 XtPopup(promotionShell, XtGrabNone);
\r
5808 promotionUp = True;
\r
5811 void PromotionPopDown()
\r
5813 if (!promotionUp) return;
\r
5814 XtPopdown(promotionShell);
\r
5815 XtDestroyWidget(promotionShell);
\r
5816 promotionUp = False;
\r
5819 void PromotionCallback(w, client_data, call_data)
\r
5821 XtPointer client_data, call_data;
\r
5827 XtSetArg(args[0], XtNlabel, &name);
\r
5828 XtGetValues(w, args, 1);
\r
5830 PromotionPopDown();
\r
5832 if (fromX == -1) return;
\r
5834 if (strcmp(name, _("cancel")) == 0) {
\r
5835 fromX = fromY = -1;
\r
5836 ClearHighlights();
\r
5838 } else if (strcmp(name, _("Knight")) == 0) {
\r
5841 promoChar = ToLower(name[0]);
\r
5844 UserMoveEvent(fromX, fromY, toX, toY, promoChar);
\r
5846 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5847 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5848 fromX = fromY = -1;
\r
5852 void ErrorCallback(w, client_data, call_data)
\r
5854 XtPointer client_data, call_data;
\r
5857 XtPopdown(w = XtParent(XtParent(XtParent(w))));
\r
5858 XtDestroyWidget(w);
\r
5859 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
\r
5863 void ErrorPopDown()
\r
5865 if (!errorUp) return;
\r
5867 XtPopdown(errorShell);
\r
5868 XtDestroyWidget(errorShell);
\r
5869 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
\r
5872 void ErrorPopUp(title, label, modal)
\r
5873 char *title, *label;
\r
5877 Widget dialog, layout;
\r
5881 Dimension bw_width, pw_width;
\r
5882 Dimension pw_height;
\r
5886 XtSetArg(args[i], XtNresizable, True); i++;
\r
5887 XtSetArg(args[i], XtNtitle, title); i++;
\r
5889 XtCreatePopupShell("errorpopup", transientShellWidgetClass,
\r
5890 shellWidget, args, i);
\r
5892 XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,
\r
5893 layoutArgs, XtNumber(layoutArgs));
\r
5896 XtSetArg(args[i], XtNlabel, label); i++;
\r
5897 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
5898 dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
\r
5901 XawDialogAddButton(dialog, _("ok"), ErrorCallback, (XtPointer) dialog);
\r
5903 XtRealizeWidget(errorShell);
\r
5904 CatchDeleteWindow(errorShell, "ErrorPopDown");
\r
5907 XtSetArg(args[i], XtNwidth, &bw_width); i++;
\r
5908 XtGetValues(boardWidget, args, i);
\r
5910 XtSetArg(args[i], XtNwidth, &pw_width); i++;
\r
5911 XtSetArg(args[i], XtNheight, &pw_height); i++;
\r
5912 XtGetValues(errorShell, args, i);
\r
5915 /* This code seems to tickle an X bug if it is executed too soon
\r
5916 after xboard starts up. The coordinates get transformed as if
\r
5917 the main window was positioned at (0, 0).
\r
5919 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
\r
5920 0 - pw_height + squareSize / 3, &x, &y);
\r
5922 XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
\r
5923 RootWindowOfScreen(XtScreen(boardWidget)),
\r
5924 (bw_width - pw_width) / 2,
\r
5925 0 - pw_height + squareSize / 3, &xx, &yy, &junk);
\r
5929 if (y < 0) y = 0; /*avoid positioning top offscreen*/
\r
5932 XtSetArg(args[i], XtNx, x); i++;
\r
5933 XtSetArg(args[i], XtNy, y); i++;
\r
5934 XtSetValues(errorShell, args, i);
\r
5937 XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);
\r
5940 /* Disable all user input other than deleting the window */
\r
5941 static int frozen = 0;
\r
5944 if (frozen) return;
\r
5945 /* Grab by a widget that doesn't accept input */
\r
5946 XtAddGrab(messageWidget, TRUE, FALSE);
\r
5950 /* Undo a FreezeUI */
\r
5953 if (!frozen) return;
\r
5954 XtRemoveGrab(messageWidget);
\r
5958 char *ModeToWidgetName(mode)
\r
5962 case BeginningOfGame:
\r
5963 if (appData.icsActive)
\r
5964 return "menuMode.ICS Client";
\r
5965 else if (appData.noChessProgram ||
\r
5966 *appData.cmailGameName != NULLCHAR)
\r
5967 return "menuMode.Edit Game";
\r
5969 return "menuMode.Machine Black";
\r
5970 case MachinePlaysBlack:
\r
5971 return "menuMode.Machine Black";
\r
5972 case MachinePlaysWhite:
\r
5973 return "menuMode.Machine White";
\r
5975 return "menuMode.Analysis Mode";
\r
5977 return "menuMode.Analyze File";
\r
5978 case TwoMachinesPlay:
\r
5979 return "menuMode.Two Machines";
\r
5981 return "menuMode.Edit Game";
\r
5982 case PlayFromGameFile:
\r
5983 return "menuFile.Load Game";
\r
5984 case EditPosition:
\r
5985 return "menuMode.Edit Position";
\r
5987 return "menuMode.Training";
\r
5988 case IcsPlayingWhite:
\r
5989 case IcsPlayingBlack:
\r
5990 case IcsObserving:
\r
5992 case IcsExamining:
\r
5993 return "menuMode.ICS Client";
\r
6000 void ModeHighlight()
\r
6003 static int oldPausing = FALSE;
\r
6004 static GameMode oldmode = (GameMode) -1;
\r
6007 if (!boardWidget || !XtIsRealized(boardWidget)) return;
\r
6009 if (pausing != oldPausing) {
\r
6010 oldPausing = pausing;
\r
6012 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6014 XtSetArg(args[0], XtNleftBitmap, None);
\r
6016 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),
\r
6019 if (appData.showButtonBar) {
\r
6022 XtSetArg(args[0], XtNbackground, buttonForegroundPixel);
\r
6023 XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);
\r
6025 XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);
\r
6026 XtSetArg(args[1], XtNforeground, buttonForegroundPixel);
\r
6029 /* Always toggle, don't set. Previous code messes up when
\r
6030 invoked while the button is pressed, as releasing it
\r
6031 toggles the state again. */
\r
6033 Pixel oldbg, oldfg;
\r
6034 XtSetArg(args[0], XtNbackground, &oldbg);
\r
6035 XtSetArg(args[1], XtNforeground, &oldfg);
\r
6036 XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),
\r
6038 XtSetArg(args[0], XtNbackground, oldfg);
\r
6039 XtSetArg(args[1], XtNforeground, oldbg);
\r
6042 XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
\r
6046 wname = ModeToWidgetName(oldmode);
\r
6047 if (wname != NULL) {
\r
6048 XtSetArg(args[0], XtNleftBitmap, None);
\r
6049 XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
\r
6051 wname = ModeToWidgetName(gameMode);
\r
6052 if (wname != NULL) {
\r
6053 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6054 XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
\r
6056 oldmode = gameMode;
\r
6058 /* Maybe all the enables should be handled here, not just this one */
\r
6059 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),
\r
6060 gameMode == Training || gameMode == PlayFromGameFile);
\r
6065 * Button/menu procedures
\r
6067 void ResetProc(w, event, prms, nprms)
\r
6074 AnalysisPopDown();
\r
6077 int LoadGamePopUp(f, gameNumber, title)
\r
6082 cmailMsgLoaded = FALSE;
\r
6083 if (gameNumber == 0) {
\r
6084 int error = GameListBuild(f);
\r
6086 DisplayError(_("Cannot build game list"), error);
\r
6087 } else if (!ListEmpty(&gameList) &&
\r
6088 ((ListGame *) gameList.tailPred)->number > 1) {
\r
6089 GameListPopUp(f, title);
\r
6092 GameListDestroy();
\r
6095 return LoadGame(f, gameNumber, title, FALSE);
\r
6098 void LoadGameProc(w, event, prms, nprms)
\r
6104 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
\r
6105 Reset(FALSE, TRUE);
\r
6107 FileNamePopUp(_("Load game file name?"), "", LoadGamePopUp, "rb");
\r
6110 void LoadNextGameProc(w, event, prms, nprms)
\r
6119 void LoadPrevGameProc(w, event, prms, nprms)
\r
6128 void ReloadGameProc(w, event, prms, nprms)
\r
6137 void LoadNextPositionProc(w, event, prms, nprms)
\r
6143 ReloadPosition(1);
\r
6146 void LoadPrevPositionProc(w, event, prms, nprms)
\r
6152 ReloadPosition(-1);
\r
6155 void ReloadPositionProc(w, event, prms, nprms)
\r
6161 ReloadPosition(0);
\r
6164 void LoadPositionProc(w, event, prms, nprms)
\r
6170 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
\r
6171 Reset(FALSE, TRUE);
\r
6173 FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
\r
6176 void SaveGameProc(w, event, prms, nprms)
\r
6182 FileNamePopUp(_("Save game file name?"),
\r
6183 DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
\r
6187 void SavePositionProc(w, event, prms, nprms)
\r
6193 FileNamePopUp(_("Save position file name?"),
\r
6194 DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
\r
6195 SavePosition, "a");
\r
6198 void ReloadCmailMsgProc(w, event, prms, nprms)
\r
6204 ReloadCmailMsgEvent(FALSE);
\r
6207 void MailMoveProc(w, event, prms, nprms)
\r
6216 /* this variable is shared between CopyPositionProc and SendPositionSelection */
\r
6217 static char *selected_fen_position=NULL;
\r
6220 SendPositionSelection(Widget w, Atom *selection, Atom *target,
\r
6221 Atom *type_return, XtPointer *value_return,
\r
6222 unsigned long *length_return, int *format_return)
\r
6224 char *selection_tmp;
\r
6226 if (!selected_fen_position) return False; /* should never happen */
\r
6227 if (*target == XA_STRING){
\r
6228 /* note: since no XtSelectionDoneProc was registered, Xt will
\r
6229 * automatically call XtFree on the value returned. So have to
\r
6230 * make a copy of it allocated with XtMalloc */
\r
6231 selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
\r
6232 strcpy(selection_tmp, selected_fen_position);
\r
6234 *value_return=selection_tmp;
\r
6235 *length_return=strlen(selection_tmp);
\r
6236 *type_return=XA_STRING;
\r
6237 *format_return = 8; /* bits per byte */
\r
6244 /* note: when called from menu all parameters are NULL, so no clue what the
\r
6245 * Widget which was clicked on was, or what the click event was
\r
6247 void CopyPositionProc(w, event, prms, nprms)
\r
6255 if (selected_fen_position) free(selected_fen_position);
\r
6256 selected_fen_position = (char *)PositionToFEN(currentMove,1);
\r
6257 if (!selected_fen_position) return;
\r
6258 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
\r
6260 SendPositionSelection,
\r
6261 NULL/* lose_ownership_proc */ ,
\r
6262 NULL/* transfer_done_proc */);
\r
6264 free(selected_fen_position);
\r
6265 selected_fen_position=NULL;
\r
6269 /* function called when the data to Paste is ready */
\r
6271 PastePositionCB(Widget w, XtPointer client_data, Atom *selection,
\r
6272 Atom *type, XtPointer value, unsigned long *len, int *format)
\r
6274 char *fenstr=value;
\r
6275 if (value==NULL || *len==0) return; /* nothing had been selected to copy */
\r
6276 fenstr[*len]='\0'; /* normally this string is terminated, but be safe */
\r
6277 EditPositionPasteFEN(fenstr);
\r
6281 /* called when Paste Position button is pressed,
\r
6282 * all parameters will be NULL */
\r
6283 void PastePositionProc(w, event, prms, nprms)
\r
6289 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
\r
6290 /* (XtSelectionCallbackProc) */ PastePositionCB,
\r
6291 NULL, /* client_data passed to PastePositionCB */
\r
6293 /* better to use the time field from the event that triggered the
\r
6294 * call to this function, but that isn't trivial to get
\r
6302 SendGameSelection(Widget w, Atom *selection, Atom *target,
\r
6303 Atom *type_return, XtPointer *value_return,
\r
6304 unsigned long *length_return, int *format_return)
\r
6306 char *selection_tmp;
\r
6308 if (*target == XA_STRING){
\r
6309 FILE* f = fopen(gameCopyFilename, "r");
\r
6312 if (f == NULL) return False;
\r
6316 selection_tmp = XtMalloc(len + 1);
\r
6317 count = fread(selection_tmp, 1, len, f);
\r
6318 if (len != count) {
\r
6319 XtFree(selection_tmp);
\r
6322 selection_tmp[len] = NULLCHAR;
\r
6323 *value_return = selection_tmp;
\r
6324 *length_return = len;
\r
6325 *type_return = XA_STRING;
\r
6326 *format_return = 8; /* bits per byte */
\r
6333 /* note: when called from menu all parameters are NULL, so no clue what the
\r
6334 * Widget which was clicked on was, or what the click event was
\r
6336 void CopyGameProc(w, event, prms, nprms)
\r
6344 ret = SaveGameToFile(gameCopyFilename, FALSE);
\r
6347 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
\r
6349 SendGameSelection,
\r
6350 NULL/* lose_ownership_proc */ ,
\r
6351 NULL/* transfer_done_proc */);
\r
6354 /* function called when the data to Paste is ready */
\r
6356 PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
\r
6357 Atom *type, XtPointer value, unsigned long *len, int *format)
\r
6360 if (value == NULL || *len == 0) {
\r
6361 return; /* nothing had been selected to copy */
\r
6363 f = fopen(gamePasteFilename, "w");
\r
6365 DisplayError(_("Can't open temp file"), errno);
\r
6368 fwrite(value, 1, *len, f);
\r
6371 LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);
\r
6374 /* called when Paste Game button is pressed,
\r
6375 * all parameters will be NULL */
\r
6376 void PasteGameProc(w, event, prms, nprms)
\r
6382 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
\r
6383 /* (XtSelectionCallbackProc) */ PasteGameCB,
\r
6384 NULL, /* client_data passed to PasteGameCB */
\r
6386 /* better to use the time field from the event that triggered the
\r
6387 * call to this function, but that isn't trivial to get
\r
6395 void AutoSaveGame()
\r
6397 SaveGameProc(NULL, NULL, NULL, NULL);
\r
6401 void QuitProc(w, event, prms, nprms)
\r
6410 void PauseProc(w, event, prms, nprms)
\r
6420 void MachineBlackProc(w, event, prms, nprms)
\r
6426 MachineBlackEvent();
\r
6429 void MachineWhiteProc(w, event, prms, nprms)
\r
6435 MachineWhiteEvent();
\r
6438 void AnalyzeModeProc(w, event, prms, nprms)
\r
6444 char buf[MSG_SIZ];
\r
6446 if (!first.analysisSupport) {
\r
6447 sprintf(buf, _("%s does not support analysis"), first.tidy);
\r
6448 DisplayError(buf, 0);
\r
6451 /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */
\r
6452 if (appData.icsActive) {
\r
6453 if (gameMode != IcsObserving) {
\r
6454 sprintf(buf,_("You are not observing a game"));
\r
6455 DisplayError(buf, 0);
\r
6456 /* secure check */
\r
6457 if (appData.icsEngineAnalyze) {
\r
6458 if (appData.debugMode)
\r
6459 fprintf(debugFP, _("Found unexpected active ICS engine analyze \n"));
\r
6460 ExitAnalyzeMode();
\r
6465 /* if enable, use want disable icsEngineAnalyze */
\r
6466 if (appData.icsEngineAnalyze) {
\r
6467 ExitAnalyzeMode();
\r
6471 appData.icsEngineAnalyze = TRUE;
\r
6472 if (appData.debugMode)
\r
6473 fprintf(debugFP, _("ICS engine analyze starting... \n"));
\r
6475 if (!appData.showThinking)
\r
6476 ShowThinkingProc(w,event,prms,nprms);
\r
6478 AnalyzeModeEvent();
\r
6481 void AnalyzeFileProc(w, event, prms, nprms)
\r
6487 if (!first.analysisSupport) {
\r
6488 char buf[MSG_SIZ];
\r
6489 sprintf(buf, _("%s does not support analysis"), first.tidy);
\r
6490 DisplayError(buf, 0);
\r
6493 Reset(FALSE, TRUE);
\r
6495 if (!appData.showThinking)
\r
6496 ShowThinkingProc(w,event,prms,nprms);
\r
6498 AnalyzeFileEvent();
\r
6499 FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
\r
6500 AnalysisPeriodicEvent(1);
\r
6503 void TwoMachinesProc(w, event, prms, nprms)
\r
6509 TwoMachinesEvent();
\r
6512 void IcsClientProc(w, event, prms, nprms)
\r
6521 void EditGameProc(w, event, prms, nprms)
\r
6530 void EditPositionProc(w, event, prms, nprms)
\r
6536 EditPositionEvent();
\r
6539 void TrainingProc(w, event, prms, nprms)
\r
6548 void EditCommentProc(w, event, prms, nprms)
\r
6555 EditCommentPopDown();
\r
6557 EditCommentEvent();
\r
6561 void IcsInputBoxProc(w, event, prms, nprms)
\r
6567 if (ICSInputBoxUp) {
\r
6568 ICSInputBoxPopDown();
\r
6570 ICSInputBoxPopUp();
\r
6574 void AcceptProc(w, event, prms, nprms)
\r
6583 void DeclineProc(w, event, prms, nprms)
\r
6592 void RematchProc(w, event, prms, nprms)
\r
6601 void CallFlagProc(w, event, prms, nprms)
\r
6610 void DrawProc(w, event, prms, nprms)
\r
6619 void AbortProc(w, event, prms, nprms)
\r
6628 void AdjournProc(w, event, prms, nprms)
\r
6637 void ResignProc(w, event, prms, nprms)
\r
6646 void EnterKeyProc(w, event, prms, nprms)
\r
6652 if (ICSInputBoxUp == True)
\r
6653 ICSInputSendText();
\r
6656 void StopObservingProc(w, event, prms, nprms)
\r
6662 StopObservingEvent();
\r
6665 void StopExaminingProc(w, event, prms, nprms)
\r
6671 StopExaminingEvent();
\r
6675 void ForwardProc(w, event, prms, nprms)
\r
6685 void BackwardProc(w, event, prms, nprms)
\r
6694 void ToStartProc(w, event, prms, nprms)
\r
6703 void ToEndProc(w, event, prms, nprms)
\r
6712 void RevertProc(w, event, prms, nprms)
\r
6721 void TruncateGameProc(w, event, prms, nprms)
\r
6727 TruncateGameEvent();
\r
6729 void RetractMoveProc(w, event, prms, nprms)
\r
6735 RetractMoveEvent();
\r
6738 void MoveNowProc(w, event, prms, nprms)
\r
6748 void AlwaysQueenProc(w, event, prms, nprms)
\r
6756 appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
\r
6758 if (appData.alwaysPromoteToQueen) {
\r
6759 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6761 XtSetArg(args[0], XtNleftBitmap, None);
\r
6763 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
\r
6767 void AnimateDraggingProc(w, event, prms, nprms)
\r
6775 appData.animateDragging = !appData.animateDragging;
\r
6777 if (appData.animateDragging) {
\r
6778 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6781 XtSetArg(args[0], XtNleftBitmap, None);
\r
6783 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
\r
6787 void AnimateMovingProc(w, event, prms, nprms)
\r
6795 appData.animate = !appData.animate;
\r
6797 if (appData.animate) {
\r
6798 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6801 XtSetArg(args[0], XtNleftBitmap, None);
\r
6803 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
\r
6807 void AutocommProc(w, event, prms, nprms)
\r
6815 appData.autoComment = !appData.autoComment;
\r
6817 if (appData.autoComment) {
\r
6818 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6820 XtSetArg(args[0], XtNleftBitmap, None);
\r
6822 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
\r
6827 void AutoflagProc(w, event, prms, nprms)
\r
6835 appData.autoCallFlag = !appData.autoCallFlag;
\r
6837 if (appData.autoCallFlag) {
\r
6838 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6840 XtSetArg(args[0], XtNleftBitmap, None);
\r
6842 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
\r
6846 void AutoflipProc(w, event, prms, nprms)
\r
6854 appData.autoFlipView = !appData.autoFlipView;
\r
6856 if (appData.autoFlipView) {
\r
6857 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6859 XtSetArg(args[0], XtNleftBitmap, None);
\r
6861 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),
\r
6865 void AutobsProc(w, event, prms, nprms)
\r
6873 appData.autoObserve = !appData.autoObserve;
\r
6875 if (appData.autoObserve) {
\r
6876 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6878 XtSetArg(args[0], XtNleftBitmap, None);
\r
6880 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
\r
6884 void AutoraiseProc(w, event, prms, nprms)
\r
6892 appData.autoRaiseBoard = !appData.autoRaiseBoard;
\r
6894 if (appData.autoRaiseBoard) {
\r
6895 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6897 XtSetArg(args[0], XtNleftBitmap, None);
\r
6899 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),
\r
6903 void AutosaveProc(w, event, prms, nprms)
\r
6911 appData.autoSaveGames = !appData.autoSaveGames;
\r
6913 if (appData.autoSaveGames) {
\r
6914 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6916 XtSetArg(args[0], XtNleftBitmap, None);
\r
6918 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
6922 void BlindfoldProc(w, event, prms, nprms)
\r
6930 appData.blindfold = !appData.blindfold;
\r
6932 if (appData.blindfold) {
\r
6933 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6935 XtSetArg(args[0], XtNleftBitmap, None);
\r
6937 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),
\r
6940 DrawPosition(True, NULL);
\r
6943 void TestLegalityProc(w, event, prms, nprms)
\r
6951 appData.testLegality = !appData.testLegality;
\r
6953 if (appData.testLegality) {
\r
6954 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6956 XtSetArg(args[0], XtNleftBitmap, None);
\r
6958 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),
\r
6963 void FlashMovesProc(w, event, prms, nprms)
\r
6971 if (appData.flashCount == 0) {
\r
6972 appData.flashCount = 3;
\r
6974 appData.flashCount = -appData.flashCount;
\r
6977 if (appData.flashCount > 0) {
\r
6978 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6980 XtSetArg(args[0], XtNleftBitmap, None);
\r
6982 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),
\r
6986 void FlipViewProc(w, event, prms, nprms)
\r
6992 flipView = !flipView;
\r
6993 DrawPosition(True, NULL);
\r
6996 void GetMoveListProc(w, event, prms, nprms)
\r
7004 appData.getMoveList = !appData.getMoveList;
\r
7006 if (appData.getMoveList) {
\r
7007 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7008 GetMoveListEvent();
\r
7010 XtSetArg(args[0], XtNleftBitmap, None);
\r
7012 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
\r
7017 void HighlightDraggingProc(w, event, prms, nprms)
\r
7025 appData.highlightDragging = !appData.highlightDragging;
\r
7027 if (appData.highlightDragging) {
\r
7028 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7030 XtSetArg(args[0], XtNleftBitmap, None);
\r
7032 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7033 "menuOptions.Highlight Dragging"), args, 1);
\r
7037 void HighlightLastMoveProc(w, event, prms, nprms)
\r
7045 appData.highlightLastMove = !appData.highlightLastMove;
\r
7047 if (appData.highlightLastMove) {
\r
7048 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7050 XtSetArg(args[0], XtNleftBitmap, None);
\r
7052 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7053 "menuOptions.Highlight Last Move"), args, 1);
\r
7056 void IcsAlarmProc(w, event, prms, nprms)
\r
7064 appData.icsAlarm = !appData.icsAlarm;
\r
7066 if (appData.icsAlarm) {
\r
7067 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7069 XtSetArg(args[0], XtNleftBitmap, None);
\r
7071 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7072 "menuOptions.ICS Alarm"), args, 1);
\r
7075 void MoveSoundProc(w, event, prms, nprms)
\r
7083 appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
\r
7085 if (appData.ringBellAfterMoves) {
\r
7086 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7088 XtSetArg(args[0], XtNleftBitmap, None);
\r
7090 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
\r
7095 void OldSaveStyleProc(w, event, prms, nprms)
\r
7103 appData.oldSaveStyle = !appData.oldSaveStyle;
\r
7105 if (appData.oldSaveStyle) {
\r
7106 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7108 XtSetArg(args[0], XtNleftBitmap, None);
\r
7110 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
\r
7114 void PeriodicUpdatesProc(w, event, prms, nprms)
\r
7122 PeriodicUpdatesEvent(!appData.periodicUpdates);
\r
7124 if (appData.periodicUpdates) {
\r
7125 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7127 XtSetArg(args[0], XtNleftBitmap, None);
\r
7129 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),
\r
7133 void PonderNextMoveProc(w, event, prms, nprms)
\r
7141 PonderNextMoveEvent(!appData.ponderNextMove);
\r
7143 if (appData.ponderNextMove) {
\r
7144 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7146 XtSetArg(args[0], XtNleftBitmap, None);
\r
7148 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
\r
7152 void PopupExitMessageProc(w, event, prms, nprms)
\r
7160 appData.popupExitMessage = !appData.popupExitMessage;
\r
7162 if (appData.popupExitMessage) {
\r
7163 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7165 XtSetArg(args[0], XtNleftBitmap, None);
\r
7167 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7168 "menuOptions.Popup Exit Message"), args, 1);
\r
7171 void PopupMoveErrorsProc(w, event, prms, nprms)
\r
7179 appData.popupMoveErrors = !appData.popupMoveErrors;
\r
7181 if (appData.popupMoveErrors) {
\r
7182 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7184 XtSetArg(args[0], XtNleftBitmap, None);
\r
7186 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),
\r
7190 void PremoveProc(w, event, prms, nprms)
\r
7198 appData.premove = !appData.premove;
\r
7200 if (appData.premove) {
\r
7201 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7203 XtSetArg(args[0], XtNleftBitmap, None);
\r
7205 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7206 "menuOptions.Premove"), args, 1);
\r
7209 void QuietPlayProc(w, event, prms, nprms)
\r
7217 appData.quietPlay = !appData.quietPlay;
\r
7219 if (appData.quietPlay) {
\r
7220 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7222 XtSetArg(args[0], XtNleftBitmap, None);
\r
7224 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
\r
7228 void ShowCoordsProc(w, event, prms, nprms)
\r
7236 appData.showCoords = !appData.showCoords;
\r
7238 if (appData.showCoords) {
\r
7239 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7241 XtSetArg(args[0], XtNleftBitmap, None);
\r
7243 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
\r
7246 DrawPosition(True, NULL);
\r
7249 void ShowThinkingProc(w, event, prms, nprms)
\r
7257 appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
\r
7258 ShowThinkingEvent();
\r
7260 // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)
\r
7261 if (appData.showThinking) {
\r
7262 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7264 XtSetArg(args[0], XtNleftBitmap, None);
\r
7266 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
\r
7271 void HideThinkingProc(w, event, prms, nprms)
\r
7279 appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
\r
7280 ShowThinkingEvent();
\r
7282 if (appData.hideThinkingFromHuman) {
\r
7283 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7285 XtSetArg(args[0], XtNleftBitmap, None);
\r
7287 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
\r
7291 void InfoProc(w, event, prms, nprms)
\r
7297 char buf[MSG_SIZ];
\r
7298 sprintf(buf, "xterm -e info --directory %s --directory . -f %s &",
\r
7299 INFODIR, INFOFILE);
\r
7303 void ManProc(w, event, prms, nprms)
\r
7309 char buf[MSG_SIZ];
\r
7311 if (nprms && *nprms > 0)
\r
7315 sprintf(buf, "xterm -e man %s &", name);
\r
7319 void HintProc(w, event, prms, nprms)
\r
7328 void BookProc(w, event, prms, nprms)
\r
7337 void AboutProc(w, event, prms, nprms)
\r
7343 char buf[MSG_SIZ];
\r
7345 char *zippy = " (with Zippy code)";
\r
7349 sprintf(buf, "%s%s\n\n%s\n%s\n%s\n%s\n\n%s%s\n%s",
\r
7350 programVersion, zippy,
\r
7351 "Copyright 1991 Digital Equipment Corporation",
\r
7352 "Enhancements Copyright 1992-2001 Free Software Foundation",
\r
7353 "Enhancements Copyright 2005 Alessandro Scotti",
\r
7354 "Enhancements Copyright 2007-2008 H.G.Muller",
\r
7355 PRODUCT, " is free software and carries NO WARRANTY;",
\r
7356 "see the file COPYING for more information.");
\r
7357 ErrorPopUp(_("About XBoard"), buf, FALSE);
\r
7360 void DebugProc(w, event, prms, nprms)
\r
7366 appData.debugMode = !appData.debugMode;
\r
7369 void AboutGameProc(w, event, prms, nprms)
\r
7378 void NothingProc(w, event, prms, nprms)
\r
7387 void Iconify(w, event, prms, nprms)
\r
7395 fromX = fromY = -1;
\r
7396 XtSetArg(args[0], XtNiconic, True);
\r
7397 XtSetValues(shellWidget, args, 1);
\r
7400 void DisplayMessage(message, extMessage)
\r
7401 char *message, *extMessage;
\r
7403 char buf[MSG_SIZ];
\r
7408 sprintf(buf, "%s %s", message, extMessage);
\r
7411 message = extMessage;
\r
7414 XtSetArg(arg, XtNlabel, message);
\r
7415 XtSetValues(messageWidget, &arg, 1);
\r
7418 void DisplayTitle(text)
\r
7423 char title[MSG_SIZ];
\r
7424 char icon[MSG_SIZ];
\r
7426 if (text == NULL) text = "";
\r
7428 if (appData.titleInWindow) {
\r
7430 XtSetArg(args[i], XtNlabel, text); i++;
\r
7431 XtSetValues(titleWidget, args, i);
\r
7434 if (*text != NULLCHAR) {
\r
7435 strcpy(icon, text);
\r
7436 strcpy(title, text);
\r
7437 } else if (appData.icsActive) {
\r
7438 sprintf(icon, "%s", appData.icsHost);
\r
7439 sprintf(title, "%s: %s", programName, appData.icsHost);
\r
7440 } else if (appData.cmailGameName[0] != NULLCHAR) {
\r
7441 sprintf(icon, "%s", "CMail");
\r
7442 sprintf(title, "%s: %s", programName, "CMail");
\r
7444 // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
\r
7445 } else if (gameInfo.variant == VariantGothic) {
\r
7446 strcpy(icon, programName);
\r
7447 strcpy(title, GOTHIC);
\r
7450 } else if (gameInfo.variant == VariantFalcon) {
\r
7451 strcpy(icon, programName);
\r
7452 strcpy(title, FALCON);
\r
7454 } else if (appData.noChessProgram) {
\r
7455 strcpy(icon, programName);
\r
7456 strcpy(title, programName);
\r
7458 strcpy(icon, first.tidy);
\r
7459 sprintf(title, "%s: %s", programName, first.tidy);
\r
7462 XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++;
\r
7463 XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++;
\r
7464 XtSetValues(shellWidget, args, i);
\r
7468 void DisplayError(message, error)
\r
7472 char buf[MSG_SIZ];
\r
7475 if (appData.debugMode || appData.matchMode) {
\r
7476 fprintf(stderr, "%s: %s\n", programName, message);
\r
7479 if (appData.debugMode || appData.matchMode) {
\r
7480 fprintf(stderr, "%s: %s: %s\n",
\r
7481 programName, message, strerror(error));
\r
7483 sprintf(buf, "%s: %s", message, strerror(error));
\r
7486 ErrorPopUp(_("Error"), message, FALSE);
\r
7490 void DisplayMoveError(message)
\r
7493 fromX = fromY = -1;
\r
7494 ClearHighlights();
\r
7495 DrawPosition(FALSE, NULL);
\r
7496 if (appData.debugMode || appData.matchMode) {
\r
7497 fprintf(stderr, "%s: %s\n", programName, message);
\r
7499 if (appData.popupMoveErrors) {
\r
7500 ErrorPopUp(_("Error"), message, FALSE);
\r
7502 DisplayMessage(message, "");
\r
7507 void DisplayFatalError(message, error, status)
\r
7509 int error, status;
\r
7511 char buf[MSG_SIZ];
\r
7513 errorExitStatus = status;
\r
7515 fprintf(stderr, "%s: %s\n", programName, message);
\r
7517 fprintf(stderr, "%s: %s: %s\n",
\r
7518 programName, message, strerror(error));
\r
7519 sprintf(buf, "%s: %s", message, strerror(error));
\r
7522 if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
\r
7523 ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
\r
7525 ExitEvent(status);
\r
7529 void DisplayInformation(message)
\r
7533 ErrorPopUp(_("Information"), message, TRUE);
\r
7536 void DisplayNote(message)
\r
7540 ErrorPopUp(_("Note"), message, FALSE);
\r
7544 NullXErrorCheck(dpy, error_event)
\r
7546 XErrorEvent *error_event;
\r
7551 void DisplayIcsInteractionTitle(message)
\r
7554 if (oldICSInteractionTitle == NULL) {
\r
7555 /* Magic to find the old window title, adapted from vim */
\r
7556 char *wina = getenv("WINDOWID");
\r
7557 if (wina != NULL) {
\r
7558 Window win = (Window) atoi(wina);
\r
7559 Window root, parent, *children;
\r
7560 unsigned int nchildren;
\r
7561 int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);
\r
7563 if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
\r
7564 if (!XQueryTree(xDisplay, win, &root, &parent,
\r
7565 &children, &nchildren)) break;
\r
7566 if (children) XFree((void *)children);
\r
7567 if (parent == root || parent == 0) break;
\r
7570 XSetErrorHandler(oldHandler);
\r
7572 if (oldICSInteractionTitle == NULL) {
\r
7573 oldICSInteractionTitle = "xterm";
\r
7576 printf("\033]0;%s\007", message);
\r
7580 char pendingReplyPrefix[MSG_SIZ];
\r
7581 ProcRef pendingReplyPR;
\r
7583 void AskQuestionProc(w, event, prms, nprms)
\r
7589 if (*nprms != 4) {
\r
7590 fprintf(stderr, _("AskQuestionProc needed 4 parameters, got %d\n"),
\r
7594 AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);
\r
7597 void AskQuestionPopDown()
\r
7599 if (!askQuestionUp) return;
\r
7600 XtPopdown(askQuestionShell);
\r
7601 XtDestroyWidget(askQuestionShell);
\r
7602 askQuestionUp = False;
\r
7605 void AskQuestionReplyAction(w, event, prms, nprms)
\r
7611 char buf[MSG_SIZ];
\r
7615 reply = XawDialogGetValueString(w = XtParent(w));
\r
7616 strcpy(buf, pendingReplyPrefix);
\r
7617 if (*buf) strcat(buf, " ");
\r
7618 strcat(buf, reply);
\r
7619 strcat(buf, "\n");
\r
7620 OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
\r
7621 AskQuestionPopDown();
\r
7623 if (err) DisplayFatalError(_("Error writing to chess program"), err, 0);
\r
7626 void AskQuestionCallback(w, client_data, call_data)
\r
7628 XtPointer client_data, call_data;
\r
7633 XtSetArg(args[0], XtNlabel, &name);
\r
7634 XtGetValues(w, args, 1);
\r
7636 if (strcmp(name, _("cancel")) == 0) {
\r
7637 AskQuestionPopDown();
\r
7639 AskQuestionReplyAction(w, NULL, NULL, NULL);
\r
7643 void AskQuestion(title, question, replyPrefix, pr)
\r
7644 char *title, *question, *replyPrefix;
\r
7648 Widget popup, layout, dialog, edit;
\r
7649 Window root, child;
\r
7652 unsigned int mask;
\r
7654 strcpy(pendingReplyPrefix, replyPrefix);
\r
7655 pendingReplyPR = pr;
\r
7658 XtSetArg(args[i], XtNresizable, True); i++;
\r
7659 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
\r
7660 askQuestionShell = popup =
\r
7661 XtCreatePopupShell(title, transientShellWidgetClass,
\r
7662 shellWidget, args, i);
\r
7665 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
\r
7666 layoutArgs, XtNumber(layoutArgs));
\r
7669 XtSetArg(args[i], XtNlabel, question); i++;
\r
7670 XtSetArg(args[i], XtNvalue, ""); i++;
\r
7671 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
7672 dialog = XtCreateManagedWidget("question", dialogWidgetClass,
\r
7675 XawDialogAddButton(dialog, _("enter"), AskQuestionCallback,
\r
7676 (XtPointer) dialog);
\r
7677 XawDialogAddButton(dialog, _("cancel"), AskQuestionCallback,
\r
7678 (XtPointer) dialog);
\r
7680 XtRealizeWidget(popup);
\r
7681 CatchDeleteWindow(popup, "AskQuestionPopDown");
\r
7683 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
\r
7684 &x, &y, &win_x, &win_y, &mask);
\r
7686 XtSetArg(args[0], XtNx, x - 10);
\r
7687 XtSetArg(args[1], XtNy, y - 30);
\r
7688 XtSetValues(popup, args, 2);
\r
7690 XtPopup(popup, XtGrabExclusive);
\r
7691 askQuestionUp = True;
\r
7693 edit = XtNameToWidget(dialog, "*value");
\r
7694 XtSetKeyboardFocus(popup, edit);
\r
7702 if (*name == NULLCHAR) {
\r
7704 } else if (strcmp(name, "$") == 0) {
\r
7705 putc(BELLCHAR, stderr);
\r
7708 sprintf(buf, "%s '%s' &", appData.soundProgram, name);
\r
7716 PlaySound(appData.soundMove);
\r
7722 PlaySound(appData.soundIcsWin);
\r
7726 PlayIcsLossSound()
\r
7728 PlaySound(appData.soundIcsLoss);
\r
7732 PlayIcsDrawSound()
\r
7734 PlaySound(appData.soundIcsDraw);
\r
7738 PlayIcsUnfinishedSound()
\r
7740 PlaySound(appData.soundIcsUnfinished);
\r
7746 PlaySound(appData.soundIcsAlarm);
\r
7752 system("stty echo");
\r
7758 system("stty -echo");
\r
7762 Colorize(cc, continuation)
\r
7766 char buf[MSG_SIZ];
\r
7767 int count, outCount, error;
\r
7769 if (textColors[(int)cc].bg > 0) {
\r
7770 if (textColors[(int)cc].fg > 0) {
\r
7771 sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
\r
7772 textColors[(int)cc].fg, textColors[(int)cc].bg);
\r
7774 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
\r
7775 textColors[(int)cc].bg);
\r
7778 if (textColors[(int)cc].fg > 0) {
\r
7779 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
\r
7780 textColors[(int)cc].fg);
\r
7782 sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);
\r
7785 count = strlen(buf);
\r
7786 outCount = OutputToProcess(NoProc, buf, count, &error);
\r
7787 if (outCount < count) {
\r
7788 DisplayFatalError(_("Error writing to display"), error, 1);
\r
7791 if (continuation) return;
\r
7794 PlaySound(appData.soundShout);
\r
7797 PlaySound(appData.soundSShout);
\r
7799 case ColorChannel1:
\r
7800 PlaySound(appData.soundChannel1);
\r
7802 case ColorChannel:
\r
7803 PlaySound(appData.soundChannel);
\r
7806 PlaySound(appData.soundKibitz);
\r
7809 PlaySound(appData.soundTell);
\r
7811 case ColorChallenge:
\r
7812 PlaySound(appData.soundChallenge);
\r
7814 case ColorRequest:
\r
7815 PlaySound(appData.soundRequest);
\r
7818 PlaySound(appData.soundSeek);
\r
7829 return getpwuid(getuid())->pw_name;
\r
7832 static char *ExpandPathName(path)
\r
7835 static char static_buf[2000];
\r
7836 char *d, *s, buf[2000];
\r
7837 struct passwd *pwd;
\r
7842 while (*s && isspace(*s))
\r
7847 return static_buf;
\r
7851 if (*(s+1) == '/') {
\r
7852 strcpy(d, getpwuid(getuid())->pw_dir);
\r
7857 *strchr(buf, '/') = 0;
\r
7858 pwd = getpwnam(buf);
\r
7861 fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
\r
7865 strcpy(d, pwd->pw_dir);
\r
7866 strcat(d, strchr(s+1, '/'));
\r
7872 return static_buf;
\r
7877 static char host_name[MSG_SIZ];
\r
7879 #if HAVE_GETHOSTNAME
\r
7880 gethostname(host_name, MSG_SIZ);
\r
7882 #else /* not HAVE_GETHOSTNAME */
\r
7883 # if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
\r
7884 sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
\r
7886 # else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
\r
7887 return "localhost";
\r
7888 # endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
\r
7889 #endif /* not HAVE_GETHOSTNAME */
\r
7892 XtIntervalId delayedEventTimerXID = 0;
\r
7893 DelayedEventCallback delayedEventCallback = 0;
\r
7896 FireDelayedEvent()
\r
7898 delayedEventTimerXID = 0;
\r
7899 delayedEventCallback();
\r
7903 ScheduleDelayedEvent(cb, millisec)
\r
7904 DelayedEventCallback cb; long millisec;
\r
7906 delayedEventCallback = cb;
\r
7907 delayedEventTimerXID =
\r
7908 XtAppAddTimeOut(appContext, millisec,
\r
7909 (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
\r
7912 DelayedEventCallback
\r
7915 if (delayedEventTimerXID) {
\r
7916 return delayedEventCallback;
\r
7923 CancelDelayedEvent()
\r
7925 if (delayedEventTimerXID) {
\r
7926 XtRemoveTimeOut(delayedEventTimerXID);
\r
7927 delayedEventTimerXID = 0;
\r
7931 XtIntervalId loadGameTimerXID = 0;
\r
7933 int LoadGameTimerRunning()
\r
7935 return loadGameTimerXID != 0;
\r
7938 int StopLoadGameTimer()
\r
7940 if (loadGameTimerXID != 0) {
\r
7941 XtRemoveTimeOut(loadGameTimerXID);
\r
7942 loadGameTimerXID = 0;
\r
7950 LoadGameTimerCallback(arg, id)
\r
7954 loadGameTimerXID = 0;
\r
7955 AutoPlayGameLoop();
\r
7959 StartLoadGameTimer(millisec)
\r
7962 loadGameTimerXID =
\r
7963 XtAppAddTimeOut(appContext, millisec,
\r
7964 (XtTimerCallbackProc) LoadGameTimerCallback,
\r
7968 XtIntervalId analysisClockXID = 0;
\r
7971 AnalysisClockCallback(arg, id)
\r
7975 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
\r
7976 || appData.icsEngineAnalyze) { // [DM]
\r
7977 AnalysisPeriodicEvent(0);
\r
7978 StartAnalysisClock();
\r
7983 StartAnalysisClock()
\r
7985 analysisClockXID =
\r
7986 XtAppAddTimeOut(appContext, 2000,
\r
7987 (XtTimerCallbackProc) AnalysisClockCallback,
\r
7991 XtIntervalId clockTimerXID = 0;
\r
7993 int ClockTimerRunning()
\r
7995 return clockTimerXID != 0;
\r
7998 int StopClockTimer()
\r
8000 if (clockTimerXID != 0) {
\r
8001 XtRemoveTimeOut(clockTimerXID);
\r
8002 clockTimerXID = 0;
\r
8010 ClockTimerCallback(arg, id)
\r
8014 clockTimerXID = 0;
\r
8015 DecrementClocks();
\r
8019 StartClockTimer(millisec)
\r
8023 XtAppAddTimeOut(appContext, millisec,
\r
8024 (XtTimerCallbackProc) ClockTimerCallback,
\r
8029 DisplayTimerLabel(w, color, timer, highlight)
\r
8035 char buf[MSG_SIZ];
\r
8038 if (appData.clockMode) {
\r
8039 sprintf(buf, "%s: %s", color, TimeString(timer));
\r
8040 XtSetArg(args[0], XtNlabel, buf);
\r
8042 sprintf(buf, "%s ", color);
\r
8043 XtSetArg(args[0], XtNlabel, buf);
\r
8047 XtSetArg(args[1], XtNbackground, timerForegroundPixel);
\r
8048 XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
\r
8050 XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
\r
8051 XtSetArg(args[2], XtNforeground, timerForegroundPixel);
\r
8054 XtSetValues(w, args, 3);
\r
8058 DisplayWhiteClock(timeRemaining, highlight)
\r
8059 long timeRemaining;
\r
8064 if(appData.noGUI) return;
\r
8065 DisplayTimerLabel(whiteTimerWidget, _("White"), timeRemaining, highlight);
\r
8066 if (highlight && iconPixmap == bIconPixmap) {
\r
8067 iconPixmap = wIconPixmap;
\r
8068 XtSetArg(args[0], XtNiconPixmap, iconPixmap);
\r
8069 XtSetValues(shellWidget, args, 1);
\r
8074 DisplayBlackClock(timeRemaining, highlight)
\r
8075 long timeRemaining;
\r
8080 if(appData.noGUI) return;
\r
8081 DisplayTimerLabel(blackTimerWidget, _("Black"), timeRemaining, highlight);
\r
8082 if (highlight && iconPixmap == wIconPixmap) {
\r
8083 iconPixmap = bIconPixmap;
\r
8084 XtSetArg(args[0], XtNiconPixmap, iconPixmap);
\r
8085 XtSetValues(shellWidget, args, 1);
\r
8094 typedef int CPKind;
\r
8099 int fdTo, fdFrom;
\r
8103 int StartChildProcess(cmdLine, dir, pr)
\r
8108 char *argv[64], *p;
\r
8110 int to_prog[2], from_prog[2];
\r
8112 char buf[MSG_SIZ];
\r
8114 if (appData.debugMode) {
\r
8115 fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
\r
8118 /* We do NOT feed the cmdLine to the shell; we just
\r
8119 parse it into blank-separated arguments in the
\r
8120 most simple-minded way possible.
\r
8123 strcpy(buf, cmdLine);
\r
8127 p = strchr(p, ' ');
\r
8128 if (p == NULL) break;
\r
8133 SetUpChildIO(to_prog, from_prog);
\r
8135 if ((pid = fork()) == 0) {
\r
8136 /* Child process */
\r
8137 // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1
\r
8138 close(to_prog[1]); // first close the unused pipe ends
\r
8139 close(from_prog[0]);
\r
8140 dup2(to_prog[0], 0); // to_prog was created first, nd is the only one to use 0 or 1
\r
8141 dup2(from_prog[1], 1);
\r
8142 if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original
\r
8143 close(from_prog[1]); // and closing again loses one of the pipes!
\r
8144 if(fileno(stderr) >= 2) // better safe than sorry...
\r
8145 dup2(1, fileno(stderr)); /* force stderr to the pipe */
\r
8147 if (dir[0] != NULLCHAR && chdir(dir) != 0) {
\r
8152 nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc
\r
8154 execvp(argv[0], argv);
\r
8156 /* If we get here, exec failed */
\r
8161 /* Parent process */
\r
8162 close(to_prog[0]);
\r
8163 close(from_prog[1]);
\r
8165 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8166 cp->kind = CPReal;
\r
8168 cp->fdFrom = from_prog[0];
\r
8169 cp->fdTo = to_prog[1];
\r
8170 *pr = (ProcRef) cp;
\r
8174 // [HGM] kill: implement the 'hard killing' of AS's Winboard_x
\r
8175 static RETSIGTYPE AlarmCallBack(int n)
\r
8181 DestroyChildProcess(pr, signalType)
\r
8185 ChildProc *cp = (ChildProc *) pr;
\r
8187 if (cp->kind != CPReal) return;
\r
8188 cp->kind = CPNone;
\r
8189 if (signalType == 10) { // [HGM] kill: if it does not terminate in 3 sec, kill
\r
8190 signal(SIGALRM, AlarmCallBack);
\r
8192 if(wait((int *) 0) == -1) { // process does not terminate on its own accord
\r
8193 kill(cp->pid, SIGKILL); // kill it forcefully
\r
8194 wait((int *) 0); // and wait again
\r
8198 kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: use hard kill if so requested
\r
8200 /* Process is exiting either because of the kill or because of
\r
8201 a quit command sent by the backend; either way, wait for it to die.
\r
8205 close(cp->fdFrom);
\r
8210 InterruptChildProcess(pr)
\r
8213 ChildProc *cp = (ChildProc *) pr;
\r
8215 if (cp->kind != CPReal) return;
\r
8216 (void) kill(cp->pid, SIGINT); /* stop it thinking */
\r
8219 int OpenTelnet(host, port, pr)
\r
8224 char cmdLine[MSG_SIZ];
\r
8226 if (port[0] == NULLCHAR) {
\r
8227 sprintf(cmdLine, "%s %s", appData.telnetProgram, host);
\r
8229 sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);
\r
8231 return StartChildProcess(cmdLine, "", pr);
\r
8234 int OpenTCP(host, port, pr)
\r
8240 DisplayFatalError(_("Socket support is not configured in"), 0, 2);
\r
8241 #else /* !OMIT_SOCKETS */
\r
8243 struct sockaddr_in sa;
\r
8244 struct hostent *hp;
\r
8245 unsigned short uport;
\r
8248 if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
\r
8252 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
\r
8253 sa.sin_family = AF_INET;
\r
8254 sa.sin_addr.s_addr = INADDR_ANY;
\r
8255 uport = (unsigned short) 0;
\r
8256 sa.sin_port = htons(uport);
\r
8257 if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
\r
8261 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
\r
8262 if (!(hp = gethostbyname(host))) {
\r
8263 int b0, b1, b2, b3;
\r
8264 if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
\r
8265 hp = (struct hostent *) calloc(1, sizeof(struct hostent));
\r
8266 hp->h_addrtype = AF_INET;
\r
8268 hp->h_addr_list = (char **) calloc(2, sizeof(char *));
\r
8269 hp->h_addr_list[0] = (char *) malloc(4);
\r
8270 hp->h_addr_list[0][0] = b0;
\r
8271 hp->h_addr_list[0][1] = b1;
\r
8272 hp->h_addr_list[0][2] = b2;
\r
8273 hp->h_addr_list[0][3] = b3;
\r
8278 sa.sin_family = hp->h_addrtype;
\r
8279 uport = (unsigned short) atoi(port);
\r
8280 sa.sin_port = htons(uport);
\r
8281 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
\r
8283 if (connect(s, (struct sockaddr *) &sa,
\r
8284 sizeof(struct sockaddr_in)) < 0) {
\r
8288 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8289 cp->kind = CPSock;
\r
8293 *pr = (ProcRef) cp;
\r
8295 #endif /* !OMIT_SOCKETS */
\r
8300 int OpenCommPort(name, pr)
\r
8307 fd = open(name, 2, 0);
\r
8308 if (fd < 0) return errno;
\r
8310 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8311 cp->kind = CPComm;
\r
8315 *pr = (ProcRef) cp;
\r
8320 int OpenLoopback(pr)
\r
8324 int to[2], from[2];
\r
8326 SetUpChildIO(to, from);
\r
8328 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8329 cp->kind = CPLoop;
\r
8331 cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */
\r
8333 *pr = (ProcRef) cp;
\r
8338 int OpenRcmd(host, user, cmd, pr)
\r
8339 char *host, *user, *cmd;
\r
8342 DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
\r
8346 #define INPUT_SOURCE_BUF_SIZE 8192
\r
8353 InputCallback func;
\r
8355 char buf[INPUT_SOURCE_BUF_SIZE];
\r
8360 DoInputCallback(closure, source, xid)
\r
8365 InputSource *is = (InputSource *) closure;
\r
8370 if (is->lineByLine) {
\r
8371 count = read(is->fd, is->unused,
\r
8372 INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
\r
8374 (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
\r
8377 is->unused += count;
\r
8379 while (p < is->unused) {
\r
8380 q = memchr(p, '\n', is->unused - p);
\r
8381 if (q == NULL) break;
\r
8383 (is->func)(is, is->closure, p, q - p, 0);
\r
8387 while (p < is->unused) {
\r
8392 count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
\r
8397 (is->func)(is, is->closure, is->buf, count, error);
\r
8401 InputSourceRef AddInputSource(pr, lineByLine, func, closure)
\r
8404 InputCallback func;
\r
8408 ChildProc *cp = (ChildProc *) pr;
\r
8410 is = (InputSource *) calloc(1, sizeof(InputSource));
\r
8411 is->lineByLine = lineByLine;
\r
8413 if (pr == NoProc) {
\r
8414 is->kind = CPReal;
\r
8415 is->fd = fileno(stdin);
\r
8417 is->kind = cp->kind;
\r
8418 is->fd = cp->fdFrom;
\r
8421 is->unused = is->buf;
\r
8424 is->xid = XtAppAddInput(appContext, is->fd,
\r
8425 (XtPointer) (XtInputReadMask),
\r
8426 (XtInputCallbackProc) DoInputCallback,
\r
8428 is->closure = closure;
\r
8429 return (InputSourceRef) is;
\r
8433 RemoveInputSource(isr)
\r
8434 InputSourceRef isr;
\r
8436 InputSource *is = (InputSource *) isr;
\r
8438 if (is->xid == 0) return;
\r
8439 XtRemoveInput(is->xid);
\r
8443 int OutputToProcess(pr, message, count, outError)
\r
8449 ChildProc *cp = (ChildProc *) pr;
\r
8453 outCount = fwrite(message, 1, count, stdout);
\r
8455 outCount = write(cp->fdTo, message, count);
\r
8457 if (outCount == -1)
\r
8458 *outError = errno;
\r
8465 /* Output message to process, with "ms" milliseconds of delay
\r
8466 between each character. This is needed when sending the logon
\r
8467 script to ICC, which for some reason doesn't like the
\r
8468 instantaneous send. */
\r
8469 int OutputToProcessDelayed(pr, message, count, outError, msdelay)
\r
8476 ChildProc *cp = (ChildProc *) pr;
\r
8481 r = write(cp->fdTo, message++, 1);
\r
8483 *outError = errno;
\r
8488 TimeDelay(msdelay);
\r
8494 /**** Animation code by Hugh Fisher, DCS, ANU.
\r
8496 Known problem: if a window overlapping the board is
\r
8497 moved away while a piece is being animated underneath,
\r
8498 the newly exposed area won't be updated properly.
\r
8499 I can live with this.
\r
8501 Known problem: if you look carefully at the animation
\r
8502 of pieces in mono mode, they are being drawn as solid
\r
8503 shapes without interior detail while moving. Fixing
\r
8504 this would be a major complication for minimal return.
\r
8507 /* Masks for XPM pieces. Black and white pieces can have
\r
8508 different shapes, but in the interest of retaining my
\r
8509 sanity pieces must have the same outline on both light
\r
8510 and dark squares, and all pieces must use the same
\r
8511 background square colors/images. */
\r
8514 CreateAnimMasks (pieceDepth)
\r
8517 ChessSquare piece;
\r
8521 unsigned long plane;
\r
8524 /* Need a bitmap just to get a GC with right depth */
\r
8525 buf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8527 values.foreground = 1;
\r
8528 values.background = 0;
\r
8529 /* Don't use XtGetGC, not read only */
\r
8530 maskGC = XCreateGC(xDisplay, buf,
\r
8531 GCForeground | GCBackground, &values);
\r
8532 XFreePixmap(xDisplay, buf);
\r
8534 buf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8535 squareSize, squareSize, pieceDepth);
\r
8536 values.foreground = XBlackPixel(xDisplay, xScreen);
\r
8537 values.background = XWhitePixel(xDisplay, xScreen);
\r
8538 bufGC = XCreateGC(xDisplay, buf,
\r
8539 GCForeground | GCBackground, &values);
\r
8541 for (piece = WhitePawn; piece <= BlackKing; piece++) {
\r
8542 /* Begin with empty mask */
\r
8543 xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
\r
8544 squareSize, squareSize, 1);
\r
8545 XSetFunction(xDisplay, maskGC, GXclear);
\r
8546 XFillRectangle(xDisplay, xpmMask[piece], maskGC,
\r
8547 0, 0, squareSize, squareSize);
\r
8549 /* Take a copy of the piece */
\r
8554 XSetFunction(xDisplay, bufGC, GXcopy);
\r
8555 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
\r
8557 0, 0, squareSize, squareSize, 0, 0);
\r
8559 /* XOR the background (light) over the piece */
\r
8560 XSetFunction(xDisplay, bufGC, GXxor);
\r
8562 XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
\r
8563 0, 0, squareSize, squareSize, 0, 0);
\r
8565 XSetForeground(xDisplay, bufGC, lightSquareColor);
\r
8566 XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
\r
8569 /* We now have an inverted piece image with the background
\r
8570 erased. Construct mask by just selecting all the non-zero
\r
8571 pixels - no need to reconstruct the original image. */
\r
8572 XSetFunction(xDisplay, maskGC, GXor);
\r
8574 /* Might be quicker to download an XImage and create bitmap
\r
8575 data from it rather than this N copies per piece, but it
\r
8576 only takes a fraction of a second and there is a much
\r
8577 longer delay for loading the pieces. */
\r
8578 for (n = 0; n < pieceDepth; n ++) {
\r
8579 XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
\r
8580 0, 0, squareSize, squareSize,
\r
8582 plane = plane << 1;
\r
8586 XFreePixmap(xDisplay, buf);
\r
8587 XFreeGC(xDisplay, bufGC);
\r
8588 XFreeGC(xDisplay, maskGC);
\r
8592 InitAnimState (anim, info)
\r
8594 XWindowAttributes * info;
\r
8599 /* Each buffer is square size, same depth as window */
\r
8600 anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8601 squareSize, squareSize, info->depth);
\r
8602 anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8603 squareSize, squareSize, info->depth);
\r
8605 /* Create a plain GC for blitting */
\r
8606 mask = GCForeground | GCBackground | GCFunction |
\r
8607 GCPlaneMask | GCGraphicsExposures;
\r
8608 values.foreground = XBlackPixel(xDisplay, xScreen);
\r
8609 values.background = XWhitePixel(xDisplay, xScreen);
\r
8610 values.function = GXcopy;
\r
8611 values.plane_mask = AllPlanes;
\r
8612 values.graphics_exposures = False;
\r
8613 anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
\r
8615 /* Piece will be copied from an existing context at
\r
8616 the start of each new animation/drag. */
\r
8617 anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
\r
8619 /* Outline will be a read-only copy of an existing */
\r
8620 anim->outlineGC = None;
\r
8626 static int done = 0;
\r
8627 XWindowAttributes info;
\r
8631 XGetWindowAttributes(xDisplay, xBoardWindow, &info);
\r
8633 InitAnimState(&game, &info);
\r
8634 InitAnimState(&player, &info);
\r
8636 /* For XPM pieces, we need bitmaps to use as masks. */
\r
8638 CreateAnimMasks(info.depth);
\r
8641 #ifndef HAVE_USLEEP
\r
8643 static Boolean frameWaiting;
\r
8645 static RETSIGTYPE FrameAlarm (sig)
\r
8648 frameWaiting = False;
\r
8649 /* In case System-V style signals. Needed?? */
\r
8650 signal(SIGALRM, FrameAlarm);
\r
8657 struct itimerval delay;
\r
8659 XSync(xDisplay, False);
\r
8662 frameWaiting = True;
\r
8663 signal(SIGALRM, FrameAlarm);
\r
8664 delay.it_interval.tv_sec =
\r
8665 delay.it_value.tv_sec = time / 1000;
\r
8666 delay.it_interval.tv_usec =
\r
8667 delay.it_value.tv_usec = (time % 1000) * 1000;
\r
8668 setitimer(ITIMER_REAL, &delay, NULL);
\r
8670 /* Ugh -- busy-wait! --tpm */
\r
8671 while (frameWaiting);
\r
8673 while (frameWaiting) pause();
\r
8675 delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
\r
8676 delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
\r
8677 setitimer(ITIMER_REAL, &delay, NULL);
\r
8687 XSync(xDisplay, False);
\r
8689 usleep(time * 1000);
\r
8694 /* Convert board position to corner of screen rect and color */
\r
8697 ScreenSquare(column, row, pt, color)
\r
8698 int column; int row; XPoint * pt; int * color;
\r
8701 pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);
\r
8702 pt->y = lineGap + row * (squareSize + lineGap);
\r
8704 pt->x = lineGap + column * (squareSize + lineGap);
\r
8705 pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);
\r
8707 *color = SquareColor(row, column);
\r
8710 /* Convert window coords to square */
\r
8713 BoardSquare(x, y, column, row)
\r
8714 int x; int y; int * column; int * row;
\r
8716 *column = EventToSquare(x, BOARD_WIDTH);
\r
8717 if (flipView && *column >= 0)
\r
8718 *column = BOARD_WIDTH - 1 - *column;
\r
8719 *row = EventToSquare(y, BOARD_HEIGHT);
\r
8720 if (!flipView && *row >= 0)
\r
8721 *row = BOARD_HEIGHT - 1 - *row;
\r
8726 #undef Max /* just in case */
\r
8728 #define Max(a, b) ((a) > (b) ? (a) : (b))
\r
8729 #define Min(a, b) ((a) < (b) ? (a) : (b))
\r
8732 SetRect(rect, x, y, width, height)
\r
8733 XRectangle * rect; int x; int y; int width; int height;
\r
8737 rect->width = width;
\r
8738 rect->height = height;
\r
8741 /* Test if two frames overlap. If they do, return
\r
8742 intersection rect within old and location of
\r
8743 that rect within new. */
\r
8746 Intersect(old, new, size, area, pt)
\r
8747 XPoint * old; XPoint * new;
\r
8748 int size; XRectangle * area; XPoint * pt;
\r
8750 if (old->x > new->x + size || new->x > old->x + size ||
\r
8751 old->y > new->y + size || new->y > old->y + size) {
\r
8754 SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0),
\r
8755 size - abs(old->x - new->x), size - abs(old->y - new->y));
\r
8756 pt->x = Max(old->x - new->x, 0);
\r
8757 pt->y = Max(old->y - new->y, 0);
\r
8762 /* For two overlapping frames, return the rect(s)
\r
8763 in the old that do not intersect with the new. */
\r
8766 CalcUpdateRects(old, new, size, update, nUpdates)
\r
8767 XPoint * old; XPoint * new; int size;
\r
8768 XRectangle update[]; int * nUpdates;
\r
8772 /* If old = new (shouldn't happen) then nothing to draw */
\r
8773 if (old->x == new->x && old->y == new->y) {
\r
8777 /* Work out what bits overlap. Since we know the rects
\r
8778 are the same size we don't need a full intersect calc. */
\r
8780 /* Top or bottom edge? */
\r
8781 if (new->y > old->y) {
\r
8782 SetRect(&(update[count]), old->x, old->y, size, new->y - old->y);
\r
8784 } else if (old->y > new->y) {
\r
8785 SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y),
\r
8786 size, old->y - new->y);
\r
8789 /* Left or right edge - don't overlap any update calculated above. */
\r
8790 if (new->x > old->x) {
\r
8791 SetRect(&(update[count]), old->x, Max(new->y, old->y),
\r
8792 new->x - old->x, size - abs(new->y - old->y));
\r
8794 } else if (old->x > new->x) {
\r
8795 SetRect(&(update[count]), new->x + size, Max(new->y, old->y),
\r
8796 old->x - new->x, size - abs(new->y - old->y));
\r
8800 *nUpdates = count;
\r
8803 /* Generate a series of frame coords from start->mid->finish.
\r
8804 The movement rate doubles until the half way point is
\r
8805 reached, then halves back down to the final destination,
\r
8806 which gives a nice slow in/out effect. The algorithmn
\r
8807 may seem to generate too many intermediates for short
\r
8808 moves, but remember that the purpose is to attract the
\r
8809 viewers attention to the piece about to be moved and
\r
8810 then to where it ends up. Too few frames would be less
\r
8814 Tween(start, mid, finish, factor, frames, nFrames)
\r
8815 XPoint * start; XPoint * mid;
\r
8816 XPoint * finish; int factor;
\r
8817 XPoint frames[]; int * nFrames;
\r
8819 int fraction, n, count;
\r
8823 /* Slow in, stepping 1/16th, then 1/8th, ... */
\r
8825 for (n = 0; n < factor; n++)
\r
8827 for (n = 0; n < factor; n++) {
\r
8828 frames[count].x = start->x + (mid->x - start->x) / fraction;
\r
8829 frames[count].y = start->y + (mid->y - start->y) / fraction;
\r
8831 fraction = fraction / 2;
\r
8835 frames[count] = *mid;
\r
8838 /* Slow out, stepping 1/2, then 1/4, ... */
\r
8840 for (n = 0; n < factor; n++) {
\r
8841 frames[count].x = finish->x - (finish->x - mid->x) / fraction;
\r
8842 frames[count].y = finish->y - (finish->y - mid->y) / fraction;
\r
8844 fraction = fraction * 2;
\r
8849 /* Draw a piece on the screen without disturbing what's there */
\r
8852 SelectGCMask(piece, clip, outline, mask)
\r
8853 ChessSquare piece; GC * clip; GC * outline; Pixmap * mask;
\r
8857 /* Bitmap for piece being moved. */
\r
8858 if (appData.monoMode) {
\r
8859 *mask = *pieceToSolid(piece);
\r
8860 } else if (useImages) {
\r
8862 *mask = xpmMask[piece];
\r
8864 *mask = ximMaskPm[piece%(int)BlackPawn];
\r
8867 *mask = *pieceToSolid(piece);
\r
8870 /* GC for piece being moved. Square color doesn't matter, but
\r
8871 since it gets modified we make a copy of the original. */
\r
8872 if (White(piece)) {
\r
8873 if (appData.monoMode)
\r
8874 source = bwPieceGC;
\r
8876 source = wlPieceGC;
\r
8878 if (appData.monoMode)
\r
8879 source = wbPieceGC;
\r
8881 source = blPieceGC;
\r
8883 XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
\r
8885 /* Outline only used in mono mode and is not modified */
\r
8887 *outline = bwPieceGC;
\r
8889 *outline = wbPieceGC;
\r
8893 OverlayPiece(piece, clip, outline, dest)
\r
8894 ChessSquare piece; GC clip; GC outline; Drawable dest;
\r
8899 /* Draw solid rectangle which will be clipped to shape of piece */
\r
8900 XFillRectangle(xDisplay, dest, clip,
\r
8901 0, 0, squareSize, squareSize);
\r
8902 if (appData.monoMode)
\r
8903 /* Also draw outline in contrasting color for black
\r
8904 on black / white on white cases */
\r
8905 XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
\r
8906 0, 0, squareSize, squareSize, 0, 0, 1);
\r
8908 /* Copy the piece */
\r
8913 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
\r
8915 0, 0, squareSize, squareSize,
\r
8920 /* Animate the movement of a single piece */
\r
8923 BeginAnimation(anim, piece, startColor, start)
\r
8925 ChessSquare piece;
\r
8931 /* The old buffer is initialised with the start square (empty) */
\r
8932 BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);
\r
8933 anim->prevFrame = *start;
\r
8935 /* The piece will be drawn using its own bitmap as a matte */
\r
8936 SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
\r
8937 XSetClipMask(xDisplay, anim->pieceGC, mask);
\r
8941 AnimationFrame(anim, frame, piece)
\r
8944 ChessSquare piece;
\r
8946 XRectangle updates[4];
\r
8947 XRectangle overlap;
\r
8951 /* Save what we are about to draw into the new buffer */
\r
8952 XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
\r
8953 frame->x, frame->y, squareSize, squareSize,
\r
8956 /* Erase bits of the previous frame */
\r
8957 if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {
\r
8958 /* Where the new frame overlapped the previous,
\r
8959 the contents in newBuf are wrong. */
\r
8960 XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
\r
8961 overlap.x, overlap.y,
\r
8962 overlap.width, overlap.height,
\r
8964 /* Repaint the areas in the old that don't overlap new */
\r
8965 CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);
\r
8966 for (i = 0; i < count; i++)
\r
8967 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8968 updates[i].x - anim->prevFrame.x,
\r
8969 updates[i].y - anim->prevFrame.y,
\r
8970 updates[i].width, updates[i].height,
\r
8971 updates[i].x, updates[i].y);
\r
8973 /* Easy when no overlap */
\r
8974 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8975 0, 0, squareSize, squareSize,
\r
8976 anim->prevFrame.x, anim->prevFrame.y);
\r
8979 /* Save this frame for next time round */
\r
8980 XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
\r
8981 0, 0, squareSize, squareSize,
\r
8983 anim->prevFrame = *frame;
\r
8985 /* Draw piece over original screen contents, not current,
\r
8986 and copy entire rect. Wipes out overlapping piece images. */
\r
8987 OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);
\r
8988 XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
\r
8989 0, 0, squareSize, squareSize,
\r
8990 frame->x, frame->y);
\r
8994 EndAnimation (anim, finish)
\r
8998 XRectangle updates[4];
\r
8999 XRectangle overlap;
\r
9003 /* The main code will redraw the final square, so we
\r
9004 only need to erase the bits that don't overlap. */
\r
9005 if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {
\r
9006 CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);
\r
9007 for (i = 0; i < count; i++)
\r
9008 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
9009 updates[i].x - anim->prevFrame.x,
\r
9010 updates[i].y - anim->prevFrame.y,
\r
9011 updates[i].width, updates[i].height,
\r
9012 updates[i].x, updates[i].y);
\r
9014 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
9015 0, 0, squareSize, squareSize,
\r
9016 anim->prevFrame.x, anim->prevFrame.y);
\r
9021 FrameSequence(anim, piece, startColor, start, finish, frames, nFrames)
\r
9023 ChessSquare piece; int startColor;
\r
9024 XPoint * start; XPoint * finish;
\r
9025 XPoint frames[]; int nFrames;
\r
9029 BeginAnimation(anim, piece, startColor, start);
\r
9030 for (n = 0; n < nFrames; n++) {
\r
9031 AnimationFrame(anim, &(frames[n]), piece);
\r
9032 FrameDelay(appData.animSpeed);
\r
9034 EndAnimation(anim, finish);
\r
9037 /* Main control logic for deciding what to animate and how */
\r
9040 AnimateMove(board, fromX, fromY, toX, toY)
\r
9047 ChessSquare piece;
\r
9049 XPoint start, finish, mid;
\r
9050 XPoint frames[kFactor * 2 + 1];
\r
9051 int nFrames, startColor, endColor;
\r
9053 /* Are we animating? */
\r
9054 if (!appData.animate || appData.blindfold)
\r
9057 if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
\r
9058 piece = board[fromY][fromX];
\r
9059 if (piece >= EmptySquare) return;
\r
9064 hop = (piece == WhiteKnight || piece == BlackKnight);
\r
9067 if (appData.debugMode) {
\r
9068 fprintf(debugFP, hop ? _("AnimateMove: piece %d hops from %d,%d to %d,%d \n") :
\r
9069 _("AnimateMove: piece %d slides from %d,%d to %d,%d \n"),
\r
9070 piece, fromX, fromY, toX, toY); }
\r
9072 ScreenSquare(fromX, fromY, &start, &startColor);
\r
9073 ScreenSquare(toX, toY, &finish, &endColor);
\r
9076 /* Knight: make diagonal movement then straight */
\r
9077 if (abs(toY - fromY) < abs(toX - fromX)) {
\r
9078 mid.x = start.x + (finish.x - start.x) / 2;
\r
9082 mid.y = start.y + (finish.y - start.y) / 2;
\r
9085 mid.x = start.x + (finish.x - start.x) / 2;
\r
9086 mid.y = start.y + (finish.y - start.y) / 2;
\r
9089 /* Don't use as many frames for very short moves */
\r
9090 if (abs(toY - fromY) + abs(toX - fromX) <= 2)
\r
9091 Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);
\r
9093 Tween(&start, &mid, &finish, kFactor, frames, &nFrames);
\r
9094 FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
\r
9096 /* Be sure end square is redrawn */
\r
9097 damage[toY][toX] = True;
\r
9101 DragPieceBegin(x, y)
\r
9104 int boardX, boardY, color;
\r
9107 /* Are we animating? */
\r
9108 if (!appData.animateDragging || appData.blindfold)
\r
9111 /* Figure out which square we start in and the
\r
9112 mouse position relative to top left corner. */
\r
9113 BoardSquare(x, y, &boardX, &boardY);
\r
9114 player.startBoardX = boardX;
\r
9115 player.startBoardY = boardY;
\r
9116 ScreenSquare(boardX, boardY, &corner, &color);
\r
9117 player.startSquare = corner;
\r
9118 player.startColor = color;
\r
9120 /* Start from exactly where the piece is. This can be confusing
\r
9121 if you start dragging far from the center of the square; most
\r
9122 or all of the piece can be over a different square from the one
\r
9123 the mouse pointer is in. */
\r
9124 player.mouseDelta.x = x - corner.x;
\r
9125 player.mouseDelta.y = y - corner.y;
\r
9127 /* As soon as we start dragging, the piece will jump slightly to
\r
9128 be centered over the mouse pointer. */
\r
9129 player.mouseDelta.x = squareSize/2;
\r
9130 player.mouseDelta.y = squareSize/2;
\r
9132 /* Initialise animation */
\r
9133 player.dragPiece = PieceForSquare(boardX, boardY);
\r
9134 /* Sanity check */
\r
9135 if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {
\r
9136 player.dragActive = True;
\r
9137 BeginAnimation(&player, player.dragPiece, color, &corner);
\r
9138 /* Mark this square as needing to be redrawn. Note that
\r
9139 we don't remove the piece though, since logically (ie
\r
9140 as seen by opponent) the move hasn't been made yet. */
\r
9141 damage[boardY][boardX] = True;
\r
9143 player.dragActive = False;
\r
9148 DragPieceMove(x, y)
\r
9153 /* Are we animating? */
\r
9154 if (!appData.animateDragging || appData.blindfold)
\r
9157 /* Sanity check */
\r
9158 if (! player.dragActive)
\r
9160 /* Move piece, maintaining same relative position
\r
9161 of mouse within square */
\r
9162 corner.x = x - player.mouseDelta.x;
\r
9163 corner.y = y - player.mouseDelta.y;
\r
9164 AnimationFrame(&player, &corner, player.dragPiece);
\r
9166 if (appData.highlightDragging) {
\r
9167 int boardX, boardY;
\r
9168 BoardSquare(x, y, &boardX, &boardY);
\r
9169 SetHighlights(fromX, fromY, boardX, boardY);
\r
9175 DragPieceEnd(x, y)
\r
9178 int boardX, boardY, color;
\r
9181 /* Are we animating? */
\r
9182 if (!appData.animateDragging || appData.blindfold)
\r
9185 /* Sanity check */
\r
9186 if (! player.dragActive)
\r
9188 /* Last frame in sequence is square piece is
\r
9189 placed on, which may not match mouse exactly. */
\r
9190 BoardSquare(x, y, &boardX, &boardY);
\r
9191 ScreenSquare(boardX, boardY, &corner, &color);
\r
9192 EndAnimation(&player, &corner);
\r
9194 /* Be sure end square is redrawn */
\r
9195 damage[boardY][boardX] = True;
\r
9197 /* This prevents weird things happening with fast successive
\r
9198 clicks which on my Sun at least can cause motion events
\r
9199 without corresponding press/release. */
\r
9200 player.dragActive = False;
\r
9203 /* Handle expose event while piece being dragged */
\r
9208 if (!player.dragActive || appData.blindfold)
\r
9211 /* What we're doing: logically, the move hasn't been made yet,
\r
9212 so the piece is still in it's original square. But visually
\r
9213 it's being dragged around the board. So we erase the square
\r
9214 that the piece is on and draw it at the last known drag point. */
\r
9215 BlankSquare(player.startSquare.x, player.startSquare.y,
\r
9216 player.startColor, EmptySquare, xBoardWindow);
\r
9217 AnimationFrame(&player, &player.prevFrame, player.dragPiece);
\r
9218 damage[player.startBoardY][player.startBoardX] = TRUE;
\r
9222 SetProgramStats( FrontEndProgramStats * stats )
\r
9225 // [HGM] done, but perhaps backend should call this directly?
\r
9226 EngineOutputUpdate( stats );
\r