-/*
- * xboard.c -- X front end for XBoard
- * $Id$
- *
- * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
- * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.
- *
- * The following terms apply to Digital Equipment Corporation's copyright
- * interest in XBoard:
- * ------------------------------------------------------------------------
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Digital not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * ------------------------------------------------------------------------
- *
- * The following terms apply to the enhanced version of XBoard distributed
- * by the Free Software Foundation:
- * ------------------------------------------------------------------------
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * ------------------------------------------------------------------------
- *
- * See the file ChangeLog for a revision history.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-
-#if !OMIT_SOCKETS
-# if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <netdb.h>
-# else /* not HAVE_SYS_SOCKET_H */
-# if HAVE_LAN_SOCKET_H
-# include <lan/socket.h>
-# include <lan/in.h>
-# include <lan/netdb.h>
-# else /* not HAVE_LAN_SOCKET_H */
-# define OMIT_SOCKETS 1
-# endif /* not HAVE_LAN_SOCKET_H */
-# endif /* not HAVE_SYS_SOCKET_H */
-#endif /* !OMIT_SOCKETS */
-
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
-#else /* not STDC_HEADERS */
-extern char *getenv();
-# if HAVE_STRING_H
-# include <string.h>
-# else /* not HAVE_STRING_H */
-# include <strings.h>
-# endif /* not HAVE_STRING_H */
-#endif /* not STDC_HEADERS */
-
-#if HAVE_SYS_FCNTL_H
-# include <sys/fcntl.h>
-#else /* not HAVE_SYS_FCNTL_H */
-# if HAVE_FCNTL_H
-# include <fcntl.h>
-# endif /* HAVE_FCNTL_H */
-#endif /* not HAVE_SYS_FCNTL_H */
-
-#if HAVE_SYS_SYSTEMINFO_H
-# include <sys/systeminfo.h>
-#endif /* HAVE_SYS_SYSTEMINFO_H */
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-# define HAVE_DIR_STRUCT
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# define HAVE_DIR_STRUCT
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# define HAVE_DIR_STRUCT
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# define HAVE_DIR_STRUCT
-# endif
-#endif
-
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Shell.h>
-#include <X11/cursorfont.h>
-#include <X11/Xatom.h>
-#if USE_XAW3D
-#include <X11/Xaw3d/Dialog.h>
-#include <X11/Xaw3d/Form.h>
-#include <X11/Xaw3d/List.h>
-#include <X11/Xaw3d/Label.h>
-#include <X11/Xaw3d/SimpleMenu.h>
-#include <X11/Xaw3d/SmeBSB.h>
-#include <X11/Xaw3d/SmeLine.h>
-#include <X11/Xaw3d/Box.h>
-#include <X11/Xaw3d/MenuButton.h>
-#include <X11/Xaw3d/Text.h>
-#include <X11/Xaw3d/AsciiText.h>
-#else
-#include <X11/Xaw/Dialog.h>
-#include <X11/Xaw/Form.h>
-#include <X11/Xaw/List.h>
-#include <X11/Xaw/Label.h>
-#include <X11/Xaw/SimpleMenu.h>
-#include <X11/Xaw/SmeBSB.h>
-#include <X11/Xaw/SmeLine.h>
-#include <X11/Xaw/Box.h>
-#include <X11/Xaw/MenuButton.h>
-#include <X11/Xaw/Text.h>
-#include <X11/Xaw/AsciiText.h>
-#endif
-
-#if HAVE_LIBXPM
-#include <X11/xpm.h>
-#include "pixmaps/pixmaps.h"
-#define IMAGE_EXT "xpm"
-#else
-#define IMAGE_EXT "xim"
-#include "bitmaps/bitmaps.h"
-#endif
-
-#include "bitmaps/icon_white.bm"
-#include "bitmaps/icon_black.bm"
-#include "bitmaps/checkmark.bm"
-
-#include "common.h"
-#include "frontend.h"
-#include "backend.h"
-#include "moves.h"
-#include "xboard.h"
-#include "childio.h"
-#include "xgamelist.h"
-#include "xhistory.h"
-#include "xedittags.h"
-
-#ifdef __EMX__
-#ifndef HAVE_USLEEP
-#define HAVE_USLEEP
-#endif
-#define usleep(t) _sleep2(((t)+500)/1000)
-#endif
-
-typedef struct {
- String string;
- XtActionProc proc;
-} MenuItem;
-
-typedef struct {
- String name;
- MenuItem *mi;
-} Menu;
-
-int main P((int argc, char **argv));
-RETSIGTYPE CmailSigHandler P((int sig));
-RETSIGTYPE IntSigHandler P((int sig));
-void CreateGCs P((void));
-void CreateXIMPieces P((void));
-void CreateXPMPieces P((void));
-void CreatePieces P((void));
-void CreatePieceMenus P((void));
-Widget CreateMenuBar P((Menu *mb));
-Widget CreateButtonBar P ((MenuItem *mi));
-char *FindFont P((char *pattern, int targetPxlSize));
-void PieceMenuPopup P((Widget w, XEvent *event,
- String *params, Cardinal *num_params));
-static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
-static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
-void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
- u_int wreq, u_int hreq));
-void CreateGrid P((void));
-int EventToSquare P((int x, int limit));
-void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
-void EventProc P((Widget widget, caddr_t unused, XEvent *event));
-void HandleUserMove P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AnimateUserMove P((Widget w, XEvent * event,
- String * params, Cardinal * nParams));
-void WhiteClock P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void BlackClock P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void DrawPositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void XDrawPosition P((Widget w, /*Boolean*/int repaint,
- Board board));
-void CommentPopUp P((char *title, char *label));
-void CommentPopDown P((void));
-void CommentCallback P((Widget w, XtPointer client_data,
- XtPointer call_data));
-void ICSInputBoxPopUp P((void));
-void ICSInputBoxPopDown P((void));
-void FileNamePopUp P((char *label, char *def,
- FileProc proc, char *openMode));
-void FileNamePopDown P((void));
-void FileNameCallback P((Widget w, XtPointer client_data,
- XtPointer call_data));
-void FileNameAction P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AskQuestionReplyAction P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AskQuestionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AskQuestionPopDown P((void));
-void PromotionPopUp P((void));
-void PromotionPopDown P((void));
-void PromotionCallback P((Widget w, XtPointer client_data,
- XtPointer call_data));
-void EditCommentPopDown P((void));
-void EditCommentCallback P((Widget w, XtPointer client_data,
- XtPointer call_data));
-void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
-void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void ReloadGameProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void LoadPositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void CopyPositionProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void PastePositionProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void SavePositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void MachineBlackProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void MachineWhiteProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AnalyzeModeProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AnalyzeFileProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void IcsClientProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void EditPositionProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void EditCommentProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void IcsInputBoxProc P((Widget w, XEvent *event,
- String *prms, Cardinal *nprms));
-void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void StopObservingProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void StopExaminingProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void TruncateGameProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void RetractMoveProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void AutocommProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutobsProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void FlashMovesProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void GetMoveListProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void TestLegalityProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
-void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void DisplayMove P((int moveNumber));
-void DisplayTitle P((char *title));
-void ICSInitScript P((void));
-int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
-void ErrorPopUp P((char *title, char *text, int modal));
-void ErrorPopDown P((void));
-static char *ExpandPathName P((char *path));
-static void CreateAnimVars P((void));
-static void DragPieceBegin P((int x, int y));
-static void DragPieceMove P((int x, int y));
-static void DragPieceEnd P((int x, int y));
-static void DrawDragPiece P((void));
-char *ModeToWidgetName P((GameMode mode));
-
-/*
-* XBoard depends on Xt R4 or higher
-*/
-int xtVersion = XtSpecificationRelease;
-
-int xScreen;
-Display *xDisplay;
-Window xBoardWindow;
-Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
- jailSquareColor, highlightSquareColor, premoveHighlightColor;
-GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
- bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
- wjPieceGC, bjPieceGC, prelineGC;
-Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
-Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
- whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
- commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
- menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
- ICSInputShell, fileNameShell, askQuestionShell;
-XSegment gridSegments[(BOARD_SIZE + 1) * 2];
-XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
-Font clockFontID, coordFontID;
-XFontStruct *clockFontStruct, *coordFontStruct;
-XtAppContext appContext;
-char *layoutName;
-char *oldICSInteractionTitle;
-
-FileProc fileProc;
-char *fileOpenMode;
-
-Position commentX = -1, commentY = -1;
-Dimension commentW, commentH;
-
-int squareSize, smallLayout = 0, tinyLayout = 0,
- fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
- ICSInputBoxUp = False, askQuestionUp = False,
- filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
- editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
-Pixel timerForegroundPixel, timerBackgroundPixel;
-Pixel buttonForegroundPixel, buttonBackgroundPixel;
-char *chessDir, *programName, *programVersion,
- *gameCopyFilename, *gamePasteFilename;
-
-#define SOLID 0
-#define OUTLINE 1
-Pixmap pieceBitmap[2][6];
-Pixmap xpmPieceBitmap[4][6]; /* LL, LD, DL, DD */
-Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
-int useImages, useImageSqs;
-XImage *ximPieceBitmap[4][6]; /* LL, LD, DL, DD */
-Pixmap ximMaskPm[6]; /* clipmasks, used for XIM pieces */
-XImage *ximLightSquare, *ximDarkSquare;
-XImage *xim_Cross;
-
-#define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % 6]
-#define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % 6]
-
-#define White(piece) ((int)(piece) < (int)BlackPawn)
-
-/* Variables for doing smooth animation. This whole thing
- would be much easier if the board was double-buffered,
- but that would require a fairly major rewrite. */
-
-typedef struct {
- Pixmap saveBuf;
- Pixmap newBuf;
- GC blitGC, pieceGC, outlineGC;
- XPoint startSquare, prevFrame, mouseDelta;
- int startColor;
- int dragPiece;
- Boolean dragActive;
- int startBoardX, startBoardY;
- } AnimState;
-
-/* There can be two pieces being animated at once: a player
- can begin dragging a piece before the remote opponent has moved. */
-
-static AnimState game, player;
-
-/* Bitmaps for use as masks when drawing XPM pieces.
- Need one for each black and white piece. */
-static Pixmap xpmMask[BlackKing + 1];
-
-/* This magic number is the number of intermediate frames used
- in each half of the animation. For short moves it's reduced
- by 1. The total number of frames will be factor * 2 + 1. */
-#define kFactor 4
-
-SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
-
-MenuItem fileMenu[] = {
- {"Reset Game", ResetProc},
- {"----", NothingProc},
- {"Load Game", LoadGameProc},
- {"Load Next Game", LoadNextGameProc},
- {"Load Previous Game", LoadPrevGameProc},
- {"Reload Same Game", ReloadGameProc},
- {"Save Game", SaveGameProc},
- {"----", NothingProc},
- {"Copy Game", CopyGameProc},
- {"Paste Game", PasteGameProc},
- {"----", NothingProc},
- {"Load Position", LoadPositionProc},
- {"Load Next Position", LoadNextPositionProc},
- {"Load Previous Position", LoadPrevPositionProc},
- {"Reload Same Position", ReloadPositionProc},
- {"Save Position", SavePositionProc},
- {"----", NothingProc},
- {"Copy Position", CopyPositionProc},
- {"Paste Position", PastePositionProc},
- {"----", NothingProc},
- {"Mail Move", MailMoveProc},
- {"Reload CMail Message", ReloadCmailMsgProc},
- {"----", NothingProc},
- {"Exit", QuitProc},
- {NULL, NULL}
-};
-
-MenuItem modeMenu[] = {
- {"Machine White", MachineWhiteProc},
- {"Machine Black", MachineBlackProc},
- {"Two Machines", TwoMachinesProc},
- {"Analysis Mode", AnalyzeModeProc},
- {"Analyze File", AnalyzeFileProc },
- {"ICS Client", IcsClientProc},
- {"Edit Game", EditGameProc},
- {"Edit Position", EditPositionProc},
- {"Training", TrainingProc},
- {"----", NothingProc},
- {"Show Game List", ShowGameListProc},
- {"Show Move List", HistoryShowProc},
- {"Edit Tags", EditTagsProc},
- {"Edit Comment", EditCommentProc},
- {"ICS Input Box", IcsInputBoxProc},
- {"Pause", PauseProc},
- {NULL, NULL}
-};
-
-MenuItem actionMenu[] = {
- {"Accept", AcceptProc},
- {"Decline", DeclineProc},
- {"Rematch", RematchProc},
- {"----", NothingProc},
- {"Call Flag", CallFlagProc},
- {"Draw", DrawProc},
- {"Adjourn", AdjournProc},
- {"Abort", AbortProc},
- {"Resign", ResignProc},
- {"----", NothingProc},
- {"Stop Observing", StopObservingProc},
- {"Stop Examining", StopExaminingProc},
- {NULL, NULL}
-};
-
-MenuItem stepMenu[] = {
- {"Backward", BackwardProc},
- {"Forward", ForwardProc},
- {"Back to Start", ToStartProc},
- {"Forward to End", ToEndProc},
- {"Revert", RevertProc},
- {"Truncate Game", TruncateGameProc},
- {"----", NothingProc},
- {"Move Now", MoveNowProc},
- {"Retract Move", RetractMoveProc},
- {NULL, NULL}
-};
-
-MenuItem optionsMenu[] = {
- {"Always Queen", AlwaysQueenProc},
- {"Animate Dragging", AnimateDraggingProc},
- {"Animate Moving", AnimateMovingProc},
- {"Auto Comment", AutocommProc},
- {"Auto Flag", AutoflagProc},
- {"Auto Flip View", AutoflipProc},
- {"Auto Observe", AutobsProc},
- {"Auto Raise Board", AutoraiseProc},
- {"Auto Save", AutosaveProc},
- {"Blindfold", BlindfoldProc},
- {"Flash Moves", FlashMovesProc},
- {"Flip View", FlipViewProc},
- {"Get Move List", GetMoveListProc},
-#if HIGHDRAG
- {"Highlight Dragging", HighlightDraggingProc},
-#endif
- {"Highlight Last Move", HighlightLastMoveProc},
- {"Move Sound", MoveSoundProc},
- {"ICS Alarm", IcsAlarmProc},
- {"Old Save Style", OldSaveStyleProc},
- {"Periodic Updates", PeriodicUpdatesProc},
- {"Ponder Next Move", PonderNextMoveProc},
- {"Popup Exit Message", PopupExitMessageProc},
- {"Popup Move Errors", PopupMoveErrorsProc},
- {"Premove", PremoveProc},
- {"Quiet Play", QuietPlayProc},
- {"Show Coords", ShowCoordsProc},
- {"Show Thinking", ShowThinkingProc},
- {"Test Legality", TestLegalityProc},
- {NULL, NULL}
-};
-
-MenuItem helpMenu[] = {
- {"Info XBoard", InfoProc},
- {"Man XBoard", ManProc},
- {"----", NothingProc},
- {"Hint", HintProc},
- {"Book", BookProc},
- {"----", NothingProc},
- {"About XBoard", AboutProc},
- {NULL, NULL}
-};
-
-Menu menuBar[] = {
- {"File", fileMenu},
- {"Mode", modeMenu},
- {"Action", actionMenu},
- {"Step", stepMenu},
- {"Options", optionsMenu},
- {"Help", helpMenu},
- {NULL, NULL}
-};
-
-#define PAUSE_BUTTON "P"
-MenuItem buttonBar[] = {
- {"<<", ToStartProc},
- {"<", BackwardProc},
- {PAUSE_BUTTON, PauseProc},
- {">", ForwardProc},
- {">>", ToEndProc},
- {NULL, NULL}
-};
-
-#define PIECE_MENU_SIZE 11
-String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
- { "White", "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",
- "----", "Empty square", "Clear board" },
- { "Black", "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",
- "----", "Empty square", "Clear board" },
- };
-/* must be in same order as PieceMenuStrings! */
-ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
- { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
- WhiteRook, WhiteQueen, WhiteKing,
- (ChessSquare) 0, EmptySquare, ClearBoard },
- { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
- BlackRook, BlackQueen, BlackKing,
- (ChessSquare) 0, EmptySquare, ClearBoard },
-};
-
-#define DROP_MENU_SIZE 6
-String dropMenuStrings[DROP_MENU_SIZE] = {
- "----", "Pawn", "Knight", "Bishop", "Rook", "Queen"
- };
-/* must be in same order as PieceMenuStrings! */
-ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
- (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
- WhiteRook, WhiteQueen
-};
-
-typedef struct {
- char piece;
- char* widget;
-} DropMenuEnables;
-
-DropMenuEnables dmEnables[] = {
- { 'P', "Pawn" },
- { 'N', "Knight" },
- { 'B', "Bishop" },
- { 'R', "Rook" },
- { 'Q', "Queen" }
-};
-
-Arg shellArgs[] = {
- { XtNwidth, 0 },
- { XtNheight, 0 },
- { XtNminWidth, 0 },
- { XtNminHeight, 0 },
- { XtNmaxWidth, 0 },
- { XtNmaxHeight, 0 }
-};
-
-Arg layoutArgs[] = {
- { XtNborderWidth, 0 },
- { XtNdefaultDistance, 0 },
-};
-
-Arg formArgs[] = {
- { XtNborderWidth, 0 },
- { XtNresizable, (XtArgVal) True },
-};
-
-Arg boardArgs[] = {
- { XtNborderWidth, 0 },
- { XtNwidth, 0 },
- { XtNheight, 0 }
-};
-
-Arg titleArgs[] = {
- { XtNjustify, (XtArgVal) XtJustifyRight },
- { XtNlabel, (XtArgVal) "..." },
- { XtNresizable, (XtArgVal) True },
- { XtNresize, (XtArgVal) False }
-};
-
-Arg messageArgs[] = {
- { XtNjustify, (XtArgVal) XtJustifyLeft },
- { XtNlabel, (XtArgVal) "..." },
- { XtNresizable, (XtArgVal) True },
- { XtNresize, (XtArgVal) False }
-};
-
-Arg timerArgs[] = {
- { XtNborderWidth, 0 },
- { XtNjustify, (XtArgVal) XtJustifyLeft }
-};
-
-XtResource clientResources[] = {
- { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
- XtOffset(AppDataPtr, whitePieceColor), XtRString,
- WHITE_PIECE_COLOR },
- { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
- XtOffset(AppDataPtr, blackPieceColor), XtRString,
- BLACK_PIECE_COLOR },
- { "lightSquareColor", "lightSquareColor", XtRString,
- sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
- XtRString, LIGHT_SQUARE_COLOR },
- { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
- XtOffset(AppDataPtr, darkSquareColor), XtRString,
- DARK_SQUARE_COLOR },
- { "highlightSquareColor", "highlightSquareColor", XtRString,
- sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
- XtRString, HIGHLIGHT_SQUARE_COLOR },
- { "premoveHighlightColor", "premoveHighlightColor", XtRString,
- sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
- XtRString, PREMOVE_HIGHLIGHT_COLOR },
- { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
- (XtPointer) MOVES_PER_SESSION },
- { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
- (XtPointer) TIME_INCREMENT },
- { "initString", "initString", XtRString, sizeof(String),
- XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
- { "secondInitString", "secondInitString", XtRString, sizeof(String),
- XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
- { "firstComputerString", "firstComputerString", XtRString,
- sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
- COMPUTER_STRING },
- { "secondComputerString", "secondComputerString", XtRString,
- sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
- COMPUTER_STRING },
- { "firstChessProgram", "firstChessProgram", XtRString,
- sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
- XtRString, FIRST_CHESS_PROGRAM },
- { "secondChessProgram", "secondChessProgram", XtRString,
- sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
- XtRString, SECOND_CHESS_PROGRAM },
- { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
- XtRImmediate, (XtPointer) False },
- { "noChessProgram", "noChessProgram", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
- XtRImmediate, (XtPointer) False },
- { "firstHost", "firstHost", XtRString, sizeof(String),
- XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
- { "secondHost", "secondHost", XtRString, sizeof(String),
- XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
- { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
- XtOffset(AppDataPtr, firstDirectory), XtRString, "" },
- { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
- XtOffset(AppDataPtr, secondDirectory), XtRString, "" },
- { "bitmapDirectory", "bitmapDirectory", XtRString,
- sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
- XtRString, "" },
- { "remoteShell", "remoteShell", XtRString, sizeof(String),
- XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
- { "remoteUser", "remoteUser", XtRString, sizeof(String),
- XtOffset(AppDataPtr, remoteUser), XtRString, "" },
- { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
- XtOffset(AppDataPtr, timeDelay), XtRString,
- (XtPointer) TIME_DELAY_QUOTE },
- { "timeControl", "timeControl", XtRString, sizeof(String),
- XtOffset(AppDataPtr, timeControl), XtRString,
- (XtPointer) TIME_CONTROL },
- { "internetChessServerMode", "internetChessServerMode",
- XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, icsActive), XtRImmediate,
- (XtPointer) False },
- { "internetChessServerHost", "internetChessServerHost",
- XtRString, sizeof(String),
- XtOffset(AppDataPtr, icsHost),
- XtRString, (XtPointer) ICS_HOST },
- { "internetChessServerPort", "internetChessServerPort",
- XtRString, sizeof(String),
- XtOffset(AppDataPtr, icsPort), XtRString,
- (XtPointer) ICS_PORT },
- { "internetChessServerCommPort", "internetChessServerCommPort",
- XtRString, sizeof(String),
- XtOffset(AppDataPtr, icsCommPort), XtRString,
- ICS_COMM_PORT },
- { "internetChessServerLogonScript", "internetChessServerLogonScript",
- XtRString, sizeof(String),
- XtOffset(AppDataPtr, icsLogon), XtRString,
- ICS_LOGON },
- { "internetChessServerHelper", "internetChessServerHelper",
- XtRString, sizeof(String),
- XtOffset(AppDataPtr, icsHelper), XtRString, "" },
- { "internetChessServerInputBox", "internetChessServerInputBox",
- XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
- (XtPointer) False },
- { "icsAlarm", "icsAlarm",
- XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
- (XtPointer) True },
- { "icsAlarmTime", "icsAlarmTime",
- XtRInt, sizeof(int),
- XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
- (XtPointer) 5000 },
- { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, useTelnet), XtRImmediate,
- (XtPointer) False },
- { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
- XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
- { "gateway", "gateway", XtRString, sizeof(String),
- XtOffset(AppDataPtr, gateway), XtRString, "" },
- { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
- XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
- { "loadGameIndex", "loadGameIndex",
- XtRInt, sizeof(int),
- XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
- (XtPointer) 0 },
- { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
- XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
- { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
- XtRImmediate, (XtPointer) True },
- { "autoSaveGames", "autoSaveGames", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
- XtRImmediate, (XtPointer) False },
- { "blindfold", "blindfold", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
- XtRImmediate, (XtPointer) False },
- { "loadPositionFile", "loadPositionFile", XtRString,
- sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
- XtRString, "" },
- { "loadPositionIndex", "loadPositionIndex",
- XtRInt, sizeof(int),
- XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
- (XtPointer) 1 },
- { "savePositionFile", "savePositionFile", XtRString,
- sizeof(String), XtOffset(AppDataPtr, savePositionFile),
- XtRString, "" },
- { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
- { "matchGames", "matchGames", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, matchGames), XtRImmediate,
- (XtPointer) 0 },
- { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, monoMode), XtRImmediate,
- (XtPointer) False },
- { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, debugMode), XtRImmediate,
- (XtPointer) False },
- { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, clockMode), XtRImmediate,
- (XtPointer) True },
- { "boardSize", "boardSize", XtRString, sizeof(String),
- XtOffset(AppDataPtr, boardSize), XtRString, "" },
- { "searchTime", "searchTime", XtRString, sizeof(String),
- XtOffset(AppDataPtr, searchTime), XtRString,
- (XtPointer) "" },
- { "searchDepth", "searchDepth", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, searchDepth), XtRImmediate,
- (XtPointer) 0 },
- { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, showCoords), XtRImmediate,
- (XtPointer) False },
- { "showJail", "showJail", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, showJail), XtRImmediate,
- (XtPointer) 0 },
- { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, showThinking), XtRImmediate,
- (XtPointer) False },
- { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
- (XtPointer) True },
- { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
- (XtPointer) True },
- { "clockFont", "clockFont", XtRString, sizeof(String),
- XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
- { "coordFont", "coordFont", XtRString, sizeof(String),
- XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
- { "font", "font", XtRString, sizeof(String),
- XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
- { "ringBellAfterMoves", "ringBellAfterMoves",
- XtRBoolean, sizeof(Boolean),
- XtOffset(AppDataPtr, ringBellAfterMoves),
- XtRImmediate, (XtPointer) False },
- { "autoCallFlag", "autoCallFlag", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
- XtRImmediate, (XtPointer) False },
- { "autoFlipView", "autoFlipView", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
- XtRImmediate, (XtPointer) True },
- { "autoObserve", "autoObserve", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
- XtRImmediate, (XtPointer) False },
- { "autoComment", "autoComment", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
- XtRImmediate, (XtPointer) False },
- { "getMoveList", "getMoveList", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
- XtRImmediate, (XtPointer) True },
-#if HIGHDRAG
- { "highlightDragging", "highlightDragging", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
- XtRImmediate, (XtPointer) False },
-#endif
- { "highlightLastMove", "highlightLastMove", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
- XtRImmediate, (XtPointer) False },
- { "premove", "premove", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, premove),
- XtRImmediate, (XtPointer) True },
- { "testLegality", "testLegality", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
- XtRImmediate, (XtPointer) True },
- { "flipView", "flipView", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, flipView),
- XtRImmediate, (XtPointer) False },
- { "cmail", "cmailGameName", XtRString, sizeof(String),
- XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
- { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
- XtRImmediate, (XtPointer) False },
- { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
- XtRImmediate, (XtPointer) False },
- { "quietPlay", "quietPlay", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
- XtRImmediate, (XtPointer) False },
- { "titleInWindow", "titleInWindow", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
- XtRImmediate, (XtPointer) False },
- { "localLineEditing", "localLineEditing", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
- XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
-#ifdef ZIPPY
- { "zippyTalk", "zippyTalk", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
- XtRImmediate, (XtPointer) ZIPPY_TALK },
- { "zippyPlay", "zippyPlay", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
- XtRImmediate, (XtPointer) ZIPPY_PLAY },
- { "zippyLines", "zippyLines", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
- { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
- { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
- { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
- { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
- ZIPPY_WRONG_PASSWORD },
- { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
- { "zippyUseI", "zippyUseI", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
- XtRImmediate, (XtPointer) ZIPPY_USE_I },
- { "zippyBughouse", "zippyBughouse", XtRInt,
- sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
- XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
- { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
- XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
- { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
- { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
- { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
- XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
- { "zippyAbort", "zippyAbort", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
- XtRImmediate, (XtPointer) ZIPPY_ABORT },
- { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
- XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
- { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
- (XtPointer) ZIPPY_MAX_GAMES },
- { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
- (XtPointer) ZIPPY_REPLAY_TIMEOUT },
-#endif
- { "flashCount", "flashCount", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, flashCount), XtRImmediate,
- (XtPointer) FLASH_COUNT },
- { "flashRate", "flashRate", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, flashRate), XtRImmediate,
- (XtPointer) FLASH_RATE },
- { "pixmapDirectory", "pixmapDirectory", XtRString,
- sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
- XtRString, "" },
- { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
- XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
- (XtPointer) MS_LOGIN_DELAY },
- { "colorizeMessages", "colorizeMessages", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, colorize),
- XtRImmediate, (XtPointer) False },
- { "colorShout", "colorShout", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorShout),
- XtRString, COLOR_SHOUT },
- { "colorSShout", "colorSShout", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorSShout),
- XtRString, COLOR_SSHOUT },
- { "colorChannel1", "colorChannel1", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorChannel1),
- XtRString, COLOR_CHANNEL1 },
- { "colorChannel", "colorChannel", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorChannel),
- XtRString, COLOR_CHANNEL },
- { "colorKibitz", "colorKibitz", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorKibitz),
- XtRString, COLOR_KIBITZ },
- { "colorTell", "colorTell", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorTell),
- XtRString, COLOR_TELL },
- { "colorChallenge", "colorChallenge", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorChallenge),
- XtRString, COLOR_CHALLENGE },
- { "colorRequest", "colorRequest", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorRequest),
- XtRString, COLOR_REQUEST },
- { "colorSeek", "colorSeek", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorSeek),
- XtRString, COLOR_SEEK },
- { "colorNormal", "colorNormal", XtRString,
- sizeof(String), XtOffset(AppDataPtr, colorNormal),
- XtRString, COLOR_NORMAL },
- { "soundProgram", "soundProgram", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundProgram),
- XtRString, "play" },
- { "soundShout", "soundShout", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundShout),
- XtRString, "" },
- { "soundSShout", "soundSShout", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundSShout),
- XtRString, "" },
- { "soundChannel1", "soundChannel1", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundChannel1),
- XtRString, "" },
- { "soundChannel", "soundChannel", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundChannel),
- XtRString, "" },
- { "soundKibitz", "soundKibitz", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundKibitz),
- XtRString, "" },
- { "soundTell", "soundTell", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundTell),
- XtRString, "" },
- { "soundChallenge", "soundChallenge", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundChallenge),
- XtRString, "" },
- { "soundRequest", "soundRequest", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundRequest),
- XtRString, "" },
- { "soundSeek", "soundSeek", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundSeek),
- XtRString, "" },
- { "soundMove", "soundMove", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundMove),
- XtRString, "$" },
- { "soundIcsWin", "soundIcsWin", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
- XtRString, "" },
- { "soundIcsLoss", "soundIcsLoss", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
- XtRString, "" },
- { "soundIcsDraw", "soundIcsDraw", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
- XtRString, "" },
- { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
- XtRString, "" },
- { "soundIcsAlarm", "soundIcsAlarm", XtRString,
- sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
- XtRString, "$" },
- { "reuseFirst", "reuseFirst", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
- XtRImmediate, (XtPointer) True },
- { "reuseSecond", "reuseSecond", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
- XtRImmediate, (XtPointer) True },
- { "animateDragging", "animateDragging", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
- XtRImmediate, (XtPointer) True },
- { "animateMoving", "animateMoving", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, animate),
- XtRImmediate, (XtPointer) True },
- { "animateSpeed", "animateSpeed", XtRInt,
- sizeof(int), XtOffset(AppDataPtr, animSpeed),
- XtRImmediate, (XtPointer)10 },
- { "popupExitMessage", "popupExitMessage", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
- XtRImmediate, (XtPointer) True },
- { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
- XtRImmediate, (XtPointer) False },
- { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
- sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
- XtRImmediate, (XtPointer)4 },
- { "initialMode", "initialMode", XtRString,
- sizeof(String), XtOffset(AppDataPtr, initialMode),
- XtRImmediate, (XtPointer) "" },
- { "variant", "variant", XtRString,
- sizeof(String), XtOffset(AppDataPtr, variant),
- XtRImmediate, (XtPointer) "normal" },
- { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
- sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
- XtRImmediate, (XtPointer)PROTOVER },
- { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
- sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
- XtRImmediate, (XtPointer)PROTOVER },
- { "showButtonBar", "showButtonBar", XtRBoolean,
- sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
- XtRImmediate, (XtPointer) True },
-};
-
-XrmOptionDescRec shellOptions[] = {
- { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
- { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
- { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
- { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
- { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
- { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
- { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
- { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
- { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
- { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
- { "-initString", "initString", XrmoptionSepArg, NULL },
- { "-firstInitString", "initString", XrmoptionSepArg, NULL },
- { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
- { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
- { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
- { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
- { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
- { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
- { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
- { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
- { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
- { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
- { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
- { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
- { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
- { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
- { "-fh", "firstHost", XrmoptionSepArg, NULL },
- { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
- { "-sh", "secondHost", XrmoptionSepArg, NULL },
- { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
- { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
- { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
- { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
- { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
- { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
- { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
- { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
- { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
- { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
- { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
- { "-td", "timeDelay", XrmoptionSepArg, NULL },
- { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
- { "-tc", "timeControl", XrmoptionSepArg, NULL },
- { "-internetChessServerMode", "internetChessServerMode",
- XrmoptionSepArg, NULL },
- { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
- { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
- { "-internetChessServerHost", "internetChessServerHost",
- XrmoptionSepArg, NULL },
- { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
- { "-internetChessServerPort", "internetChessServerPort",
- XrmoptionSepArg, NULL },
- { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
- { "-internetChessServerCommPort", "internetChessServerCommPort",
- XrmoptionSepArg, NULL },
- { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
- { "-internetChessServerLogonScript", "internetChessServerLogonScript",
- XrmoptionSepArg, NULL },
- { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
- { "-internetChessServerHelper", "internetChessServerHelper",
- XrmoptionSepArg, NULL },
- { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
- { "-internetChessServerInputBox", "internetChessServerInputBox",
- XrmoptionSepArg, NULL },
- { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
- { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
- { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
- { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
- { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
- { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
- { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
- { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
- { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
- { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
- { "-gateway", "gateway", XrmoptionSepArg, NULL },
- { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
- { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
- { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
- { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
- { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
- { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
- { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
- { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
- { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
- { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
- { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
- { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
- { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
- { "-blind", "blindfold", XrmoptionNoArg, "True" },
- { "-xblind", "blindfold", XrmoptionNoArg, "False" },
- { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
- { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
- { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
- { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
- { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
- { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
- { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
- { "-mm", "matchMode", XrmoptionNoArg, "True" },
- { "-xmm", "matchMode", XrmoptionNoArg, "False" },
- { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
- { "-mg", "matchGames", XrmoptionSepArg, NULL },
- { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
- { "-mono", "monoMode", XrmoptionNoArg, "True" },
- { "-xmono", "monoMode", XrmoptionNoArg, "False" },
- { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
- { "-debug", "debugMode", XrmoptionNoArg, "True" },
- { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
- { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
- { "-clock", "clockMode", XrmoptionNoArg, "True" },
- { "-xclock", "clockMode", XrmoptionNoArg, "False" },
- { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
- { "-size", "boardSize", XrmoptionSepArg, NULL },
- { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
- { "-st", "searchTime", XrmoptionSepArg, NULL },
- { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
- { "-depth", "searchDepth", XrmoptionSepArg, NULL },
- { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
- { "-coords", "showCoords", XrmoptionNoArg, "True" },
- { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
-#if JAIL
- { "-showJail", "showJail", XrmoptionSepArg, NULL },
- { "-jail", "showJail", XrmoptionNoArg, "1" },
- { "-sidejail", "showJail", XrmoptionNoArg, "2" },
- { "-xjail", "showJail", XrmoptionNoArg, "0" },
-#endif
- { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
- { "-thinking", "showThinking", XrmoptionNoArg, "True" },
- { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
- { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
- { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
- { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
- { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
- { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
- { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
- { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
- { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
- { "-font", "font", XrmoptionSepArg, NULL },
- { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
- { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
- { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
- { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
- { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
- { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
- { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
- { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
- { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
- { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
- { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
- { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
- { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
- { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
- { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
- { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
- { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
- { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
- { "-moves", "getMoveList", XrmoptionNoArg, "True" },
- { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
-#if HIGHDRAG
- { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
- { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
- { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
-#endif
- { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
- { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
- { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
- { "-premove", "premove", XrmoptionSepArg, NULL },
- { "-pre", "premove", XrmoptionNoArg, "True" },
- { "-xpre", "premove", XrmoptionNoArg, "False" },
- { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
- { "-legal", "testLegality", XrmoptionNoArg, "True" },
- { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
- { "-flipView", "flipView", XrmoptionSepArg, NULL },
- { "-flip", "flipView", XrmoptionNoArg, "True" },
- { "-xflip", "flipView", XrmoptionNoArg, "False" },
- { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
- { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
- XrmoptionSepArg, NULL },
- { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
- { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
- { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
- { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
- { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
- { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
- { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
- { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
- { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
- { "-title", "titleInWindow", XrmoptionNoArg, "True" },
- { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
-#ifdef ZIPPY
- { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
- { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
- { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
- { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
- { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
- { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
- { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
- { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
- { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
- { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
- { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
- { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
- { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
- { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
- { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
- { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
- { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
- { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
- { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
- { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
- { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
- { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
- { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
- { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
- { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
- { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
- { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
- { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
- { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
- { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
-#endif
- { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
- { "-flash", "flashCount", XrmoptionNoArg, "3" },
- { "-xflash", "flashCount", XrmoptionNoArg, "0" },
- { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
- { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
- { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
- { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
- { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
- { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
- { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
- { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
- { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
- { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
- { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
- { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
- { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
- { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
- { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
- { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
- { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
- { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
- { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
- { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
- { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
- { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
- { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
- { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
- { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
- { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
- { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
- { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
- { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
- { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
- { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
- { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
- { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
- { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
- { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
- { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
- { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
- { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
- { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
- { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
- { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
- { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
- { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
- { "-animate", "animateMoving", XrmoptionNoArg, "True" },
- { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
- { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
- { "-drag", "animateDragging", XrmoptionNoArg, "True" },
- { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
- { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
- { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
- { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
- { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
- { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
- { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
- { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
- { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
- { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
- { "-mode", "initialMode", XrmoptionSepArg, NULL },
- { "-variant", "variant", XrmoptionSepArg, NULL },
- { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
- { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
- { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
- { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
- { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
-};
-
-
-XtActionsRec boardActions[] = {
- { "DrawPosition", DrawPositionProc },
- { "HandleUserMove", HandleUserMove },
- { "AnimateUserMove", AnimateUserMove },
- { "FileNameAction", FileNameAction },
- { "AskQuestionProc", AskQuestionProc },
- { "AskQuestionReplyAction", AskQuestionReplyAction },
- { "PieceMenuPopup", PieceMenuPopup },
- { "WhiteClock", WhiteClock },
- { "BlackClock", BlackClock },
- { "Iconify", Iconify },
- { "ResetProc", ResetProc },
- { "LoadGameProc", LoadGameProc },
- { "LoadNextGameProc", LoadNextGameProc },
- { "LoadPrevGameProc", LoadPrevGameProc },
- { "LoadSelectedProc", LoadSelectedProc },
- { "ReloadGameProc", ReloadGameProc },
- { "LoadPositionProc", LoadPositionProc },
- { "LoadNextPositionProc", LoadNextPositionProc },
- { "LoadPrevPositionProc", LoadPrevPositionProc },
- { "ReloadPositionProc", ReloadPositionProc },
- { "CopyPositionProc", CopyPositionProc },
- { "PastePositionProc", PastePositionProc },
- { "CopyGameProc", CopyGameProc },
- { "PasteGameProc", PasteGameProc },
- { "SaveGameProc", SaveGameProc },
- { "SavePositionProc", SavePositionProc },
- { "MailMoveProc", MailMoveProc },
- { "ReloadCmailMsgProc", ReloadCmailMsgProc },
- { "QuitProc", QuitProc },
- { "MachineWhiteProc", MachineWhiteProc },
- { "MachineBlackProc", MachineBlackProc },
- { "AnalysisModeProc", AnalyzeModeProc },
- { "AnalyzeFileProc", AnalyzeFileProc },
- { "TwoMachinesProc", TwoMachinesProc },
- { "IcsClientProc", IcsClientProc },
- { "EditGameProc", EditGameProc },
- { "EditPositionProc", EditPositionProc },
- { "TrainingProc", EditPositionProc },
- { "ShowGameListProc", ShowGameListProc },
- { "ShowMoveListProc", HistoryShowProc},
- { "EditTagsProc", EditCommentProc },
- { "EditCommentProc", EditCommentProc },
- { "IcsAlarmProc", IcsAlarmProc },
- { "IcsInputBoxProc", IcsInputBoxProc },
- { "PauseProc", PauseProc },
- { "AcceptProc", AcceptProc },
- { "DeclineProc", DeclineProc },
- { "RematchProc", RematchProc },
- { "CallFlagProc", CallFlagProc },
- { "DrawProc", DrawProc },
- { "AdjournProc", AdjournProc },
- { "AbortProc", AbortProc },
- { "ResignProc", ResignProc },
- { "EnterKeyProc", EnterKeyProc },
- { "StopObservingProc", StopObservingProc },
- { "StopExaminingProc", StopExaminingProc },
- { "BackwardProc", BackwardProc },
- { "ForwardProc", ForwardProc },
- { "ToStartProc", ToStartProc },
- { "ToEndProc", ToEndProc },
- { "RevertProc", RevertProc },
- { "TruncateGameProc", TruncateGameProc },
- { "MoveNowProc", MoveNowProc },
- { "RetractMoveProc", RetractMoveProc },
- { "AlwaysQueenProc", AlwaysQueenProc },
- { "AnimateDraggingProc", AnimateDraggingProc },
- { "AnimateMovingProc", AnimateMovingProc },
- { "AutoflagProc", AutoflagProc },
- { "AutoflipProc", AutoflipProc },
- { "AutobsProc", AutobsProc },
- { "AutoraiseProc", AutoraiseProc },
- { "AutosaveProc", AutosaveProc },
- { "BlindfoldProc", BlindfoldProc },
- { "FlashMovesProc", FlashMovesProc },
- { "FlipViewProc", FlipViewProc },
- { "GetMoveListProc", GetMoveListProc },
-#if HIGHDRAG
- { "HighlightDraggingProc", HighlightDraggingProc },
-#endif
- { "HighlightLastMoveProc", HighlightLastMoveProc },
- { "IcsAlarmProc", IcsAlarmProc },
- { "MoveSoundProc", MoveSoundProc },
- { "OldSaveStyleProc", OldSaveStyleProc },
- { "PeriodicUpdatesProc", PeriodicUpdatesProc },
- { "PonderNextMoveProc", PonderNextMoveProc },
- { "PopupExitMessageProc", PopupExitMessageProc },
- { "PopupMoveErrorsProc", PopupMoveErrorsProc },
- { "PremoveProc", PremoveProc },
- { "QuietPlayProc", QuietPlayProc },
- { "ShowCoordsProc", ShowCoordsProc },
- { "ShowThinkingProc", ShowThinkingProc },
- { "TestLegalityProc", TestLegalityProc },
- { "InfoProc", InfoProc },
- { "ManProc", ManProc },
- { "HintProc", HintProc },
- { "BookProc", BookProc },
- { "AboutGameProc", AboutGameProc },
- { "AboutProc", AboutProc },
- { "DebugProc", DebugProc },
- { "NothingProc", NothingProc },
- { "CommentPopDown", (XtActionProc) CommentPopDown },
- { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
- { "TagsPopDown", (XtActionProc) TagsPopDown },
- { "ErrorPopDown", (XtActionProc) ErrorPopDown },
- { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
- { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
- { "FileNamePopDown", (XtActionProc) FileNamePopDown },
- { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
- { "GameListPopDown", (XtActionProc) GameListPopDown },
- { "PromotionPopDown", (XtActionProc) PromotionPopDown },
- { "HistoryPopDown", (XtActionProc) HistoryPopDown },
-};
-
-char globalTranslations[] =
- ":<Key>R: ResignProc() \n \
- :<Key>r: ResetProc() \n \
- :<Key>g: LoadGameProc() \n \
- :<Key>N: LoadNextGameProc() \n \
- :<Key>P: LoadPrevGameProc() \n \
- :<Key>Q: QuitProc() \n \
- :<Key>F: ToEndProc() \n \
- :<Key>f: ForwardProc() \n \
- :<Key>B: ToStartProc() \n \
- :<Key>b: BackwardProc() \n \
- :<Key>p: PauseProc() \n \
- :<Key>d: DrawProc() \n \
- :<Key>t: CallFlagProc() \n \
- :<Key>i: Iconify() \n \
- :<Key>c: Iconify() \n \
- :<Key>v: FlipViewProc() \n \
- <KeyDown>Control_L: BackwardProc() \n \
- <KeyUp>Control_L: ForwardProc() \n \
- <KeyDown>Control_R: BackwardProc() \n \
- <KeyUp>Control_R: ForwardProc() \n \
- Shift<Key>1: AskQuestionProc(\"Direct command\",\
- \"Send to chess program:\",,1) \n \
- Shift<Key>2: AskQuestionProc(\"Direct command\",\
- \"Send to second chess program:\",,2) \n";
-
-char boardTranslations[] =
- "<Btn1Down>: HandleUserMove() \n \
- <Btn1Up>: HandleUserMove() \n \
- <Btn1Motion>: AnimateUserMove() \n \
- Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
- PieceMenuPopup(menuB) \n \
- Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
- PieceMenuPopup(menuW) \n \
- Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
- PieceMenuPopup(menuW) \n \
- Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
- PieceMenuPopup(menuB) \n";
-
-char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
-char blackTranslations[] = "<BtnDown>: BlackClock()\n";
-
-char ICSInputTranslations[] =
- "<Key>Return: EnterKeyProc() \n";
-
-String xboardResources[] = {
- "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
- "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
- "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
- NULL
- };
-
-
-/* Max possible square size */
-#define MAXSQSIZE 256
-
-static int xpm_avail[MAXSQSIZE];
-
-#ifdef HAVE_DIR_STRUCT
-
-/* Extract piece size from filename */
-static int
-xpm_getsize(name, len, ext)
- char *name;
- int len;
- char *ext;
-{
- char *p, *d;
- char buf[10];
-
- if (len < 4)
- return 0;
-
- if ((p=strchr(name, '.')) == NULL ||
- StrCaseCmp(p+1, ext) != 0)
- return 0;
-
- p = name + 3;
- d = buf;
-
- while (*p && isdigit(*p))
- *(d++) = *(p++);
-
- *d = 0;
- return atoi(buf);
-}
-
-/* Setup xpm_avail */
-static int
-xpm_getavail(dirname, ext)
- char *dirname;
- char *ext;
-{
- DIR *dir;
- struct dirent *ent;
- int i;
-
- for (i=0; i<MAXSQSIZE; ++i)
- xpm_avail[i] = 0;
-
- if (appData.debugMode)
- fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
-
- dir = opendir(dirname);
- if (!dir)
- {
- fprintf(stderr, "%s: Can't access XPM directory %s\n",
- programName, dirname);
- exit(1);
- }
-
- while ((ent=readdir(dir)) != NULL) {
- i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
- if (i > 0 && i < MAXSQSIZE)
- xpm_avail[i] = 1;
- }
-
- closedir(dir);
-
- return 0;
-}
-
-void
-xpm_print_avail(fp, ext)
- FILE *fp;
- char *ext;
-{
- int i;
-
- fprintf(fp, "Available `%s' sizes:\n", ext);
- for (i=1; i<MAXSQSIZE; ++i) {
- if (xpm_avail[i])
- printf("%d\n", i);
- }
-}
-
-/* Return XPM piecesize closest to size */
-int
-xpm_closest_to(dirname, size, ext)
- char *dirname;
- int size;
- char *ext;
-{
- int i;
- int sm_diff = MAXSQSIZE;
- int sm_index = 0;
- int diff;
-
- xpm_getavail(dirname, ext);
-
- if (appData.debugMode)
- xpm_print_avail(stderr, ext);
-
- for (i=1; i<MAXSQSIZE; ++i) {
- if (xpm_avail[i]) {
- diff = size - i;
- diff = (diff<0) ? -diff : diff;
- if (diff < sm_diff) {
- sm_diff = diff;
- sm_index = i;
- }
- }
- }
-
- if (!sm_index) {
- fprintf(stderr, "Error: No `%s' files!\n", ext);
- exit(1);
- }
-
- return sm_index;
-}
-#else /* !HAVE_DIR_STRUCT */
-/* If we are on a system without a DIR struct, we can't
- read the directory, so we can't collect a list of
- filenames, etc., so we can't do any size-fitting. */
-int
-xpm_closest_to(dirname, size, ext)
- char *dirname;
- int size;
- char *ext;
-{
- fprintf(stderr, "Warning: No DIR structure found on this system --\n");
- fprintf(stderr, " Unable to autosize for XPM/XIM pieces.\n");
- fprintf(stderr, " Please report this error to frankm@hiwaay.net.\n");
- fprintf(stderr, " Include system type & operating system in message.\n");
- return size;
-}
-#endif /* HAVE_DIR_STRUCT */
-
-static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
- "magenta", "cyan", "white" };
-typedef struct {
- int attr, bg, fg;
-} TextColors;
-TextColors textColors[(int)NColorClasses];
-
-/* String is: "fg, bg, attr". Which is 0, 1, 2 */
-static int
-parse_color(str, which)
- char *str;
- int which;
-{
- char *p, buf[100], *d;
- int i;
-
- if (strlen(str) > 99) /* watch bounds on buf */
- return -1;
-
- p = str;
- d = buf;
- for (i=0; i<which; ++i) {
- p = strchr(p, ',');
- if (!p)
- return -1;
- ++p;
- }
-
- /* Could be looking at something like:
- black, , 1
- .. in which case we want to stop on a comma also */
- while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
- ++p;
-
- if (*p == ',') {
- return -1; /* Use default for empty field */
- }
-
- if (which == 2 || isdigit(*p))
- return atoi(p);
-
- while (*p && isalpha(*p))
- *(d++) = *(p++);
-
- *d = 0;
-
- for (i=0; i<8; ++i) {
- if (!StrCaseCmp(buf, cnames[i]))
- return which? (i+40) : (i+30);
- }
- if (!StrCaseCmp(buf, "default")) return -1;
-
- fprintf(stderr, "%s: unrecognized color %s\n", programName, buf);
- return -2;
-}
-
-static int
-parse_cpair(cc, str)
- ColorClass cc;
- char *str;
-{
- if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
- fprintf(stderr, "%s: can't parse foreground color in `%s'\n",
- programName, str);
- return -1;
- }
-
- /* bg and attr are optional */
- textColors[(int)cc].bg = parse_color(str, 1);
- if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
- textColors[(int)cc].attr = 0;
- }
- return 0;
-}
-
-
-/* Arrange to catch delete-window events */
-Atom wm_delete_window;
-void
-CatchDeleteWindow(Widget w, String procname)
-{
- char buf[MSG_SIZ];
- XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
- sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
- XtAugmentTranslations(w, XtParseTranslationTable(buf));
-}
-
-void
-BoardToTop()
-{
- Arg args[16];
- XtSetArg(args[0], XtNiconic, False);
- XtSetValues(shellWidget, args, 1);
-
- XtPopup(shellWidget, XtGrabNone); /* Raise if lowered */
-}
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
- XSetWindowAttributes window_attributes;
- Arg args[16];
- Dimension timerWidth, boardWidth, w, h, sep, bor, wr, hr;
- XrmValue vFrom, vTo;
- XtGeometryResult gres;
- char *p;
- XrmDatabase xdb;
- int forceMono = False;
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
- debugFP = stderr;
-
- programName = strrchr(argv[0], '/');
- if (programName == NULL)
- programName = argv[0];
- else
- programName++;
-
- shellWidget =
- XtAppInitialize(&appContext, "XBoard", shellOptions,
- XtNumber(shellOptions),
- &argc, argv, xboardResources, NULL, 0);
- if (argc > 1) {
- fprintf(stderr, "%s: unrecognized argument %s\n",
- programName, argv[1]);
- exit(2);
- }
-
- if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
- chessDir = ".";
- } else {
- if (chdir(chessDir) != 0) {
- fprintf(stderr, "%s: can't cd to CHESSDIR: ", programName);
- perror(chessDir);
- exit(1);
- }
- }
-
- p = getenv("HOME");
- if (p == NULL) p = "/tmp";
- i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
- gameCopyFilename = (char*) malloc(i);
- gamePasteFilename = (char*) malloc(i);
- sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
- sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
-
- XtGetApplicationResources(shellWidget, (XtPointer) &appData,
- clientResources, XtNumber(clientResources),
- NULL, 0);
-
-#if !HIGHDRAG
- /* This feature does not work; animation needs a rewrite */
- appData.highlightDragging = FALSE;
-#endif
- InitBackEnd1();
-
- xDisplay = XtDisplay(shellWidget);
- xScreen = DefaultScreen(xDisplay);
- wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
-
- /*
- * Determine boardSize
- */
- if (isdigit(appData.boardSize[0])) {
- i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
- &lineGap, &clockFontPxlSize, &coordFontPxlSize,
- &fontPxlSize, &smallLayout, &tinyLayout);
- if (i == 0) {
- fprintf(stderr, "%s: bad boardSize syntax %s\n",
- programName, appData.boardSize);
- exit(2);
- }
- if (i < 7) {
- /* Find some defaults; use the nearest known size */
- SizeDefaults *szd, *nearest;
- int distance = 99999;
- nearest = szd = sizeDefaults;
- while (szd->name != NULL) {
- if (abs(szd->squareSize - squareSize) < distance) {
- nearest = szd;
- distance = abs(szd->squareSize - squareSize);
- if (distance == 0) break;
- }
- szd++;
- }
- if (i < 2) lineGap = nearest->lineGap;
- if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
- if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
- if (i < 5) fontPxlSize = nearest->fontPxlSize;
- if (i < 6) smallLayout = nearest->smallLayout;
- if (i < 7) tinyLayout = nearest->tinyLayout;
- }
- } else {
- SizeDefaults *szd = sizeDefaults;
- if (*appData.boardSize == NULLCHAR) {
- while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
- DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
- szd++;
- }
- if (szd->name == NULL) szd--;
- } else {
- while (szd->name != NULL &&
- StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
- if (szd->name == NULL) {
- fprintf(stderr, "%s: unrecognized boardSize name %s\n",
- programName, appData.boardSize);
- exit(2);
- }
- }
- squareSize = szd->squareSize;
- lineGap = szd->lineGap;
- clockFontPxlSize = szd->clockFontPxlSize;
- coordFontPxlSize = szd->coordFontPxlSize;
- fontPxlSize = szd->fontPxlSize;
- smallLayout = szd->smallLayout;
- tinyLayout = szd->tinyLayout;
- }
-
- /* Now, using squareSize as a hint, find a good XPM/XIM set size */
- if (strlen(appData.pixmapDirectory) > 0) {
- p = ExpandPathName(appData.pixmapDirectory);
- if (!p) {
- fprintf(stderr, "Error expanding path name \"%s\"\n",
- appData.pixmapDirectory);
- exit(1);
- }
- if (appData.debugMode) {
- fprintf(stderr, "XBoard square size (hint): %d\n", squareSize);
- fprintf(stderr, "%s fulldir:%s:\n", IMAGE_EXT, p);
- }
- squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
- if (appData.debugMode) {
- fprintf(stderr, "Closest %s size: %d\n", IMAGE_EXT, squareSize);
- }
- }
-
- boardWidth = lineGap + BOARD_SIZE * (squareSize + lineGap);
- if (appData.showJail == 1) {
- /* Jail on top and bottom */
- XtSetArg(boardArgs[1], XtNwidth, boardWidth);
- XtSetArg(boardArgs[2], XtNheight,
- boardWidth + 2*(lineGap + squareSize));
- } else if (appData.showJail == 2) {
- /* Jail on sides */
- XtSetArg(boardArgs[1], XtNwidth,
- boardWidth + 2*(lineGap + squareSize));
- XtSetArg(boardArgs[2], XtNheight, boardWidth);
- } else {
- /* No jail */
- XtSetArg(boardArgs[1], XtNwidth, boardWidth);
- XtSetArg(boardArgs[2], XtNheight, boardWidth);
- }
-
- /*
- * Determine what fonts to use.
- */
- appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
- clockFontID = XLoadFont(xDisplay, appData.clockFont);
- clockFontStruct = XQueryFont(xDisplay, clockFontID);
- appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
- coordFontID = XLoadFont(xDisplay, appData.coordFont);
- coordFontStruct = XQueryFont(xDisplay, coordFontID);
- appData.font = FindFont(appData.font, fontPxlSize);
-
- xdb = XtDatabase(xDisplay);
- XrmPutStringResource(&xdb, "*font", appData.font);
-
- /*
- * Detect if there are not enough colors available and adapt.
- */
- if (DefaultDepth(xDisplay, xScreen) <= 2) {
- appData.monoMode = True;
- }
-
- if (!appData.monoMode) {
- vFrom.addr = (caddr_t) appData.lightSquareColor;
- vFrom.size = strlen(appData.lightSquareColor);
- XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL) {
- appData.monoMode = True;
- forceMono = True;
- } else {
- lightSquareColor = *(Pixel *) vTo.addr;
- }
- }
- if (!appData.monoMode) {
- vFrom.addr = (caddr_t) appData.darkSquareColor;
- vFrom.size = strlen(appData.darkSquareColor);
- XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL) {
- appData.monoMode = True;
- forceMono = True;
- } else {
- darkSquareColor = *(Pixel *) vTo.addr;
- }
- }
- if (!appData.monoMode) {
- vFrom.addr = (caddr_t) appData.whitePieceColor;
- vFrom.size = strlen(appData.whitePieceColor);
- XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL) {
- appData.monoMode = True;
- forceMono = True;
- } else {
- whitePieceColor = *(Pixel *) vTo.addr;
- }
- }
- if (!appData.monoMode) {
- vFrom.addr = (caddr_t) appData.blackPieceColor;
- vFrom.size = strlen(appData.blackPieceColor);
- XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL) {
- appData.monoMode = True;
- forceMono = True;
- } else {
- blackPieceColor = *(Pixel *) vTo.addr;
- }
- }
-
- if (!appData.monoMode) {
- vFrom.addr = (caddr_t) appData.highlightSquareColor;
- vFrom.size = strlen(appData.highlightSquareColor);
- XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL) {
- appData.monoMode = True;
- forceMono = True;
- } else {
- highlightSquareColor = *(Pixel *) vTo.addr;
- }
- }
-
- if (!appData.monoMode) {
- vFrom.addr = (caddr_t) appData.premoveHighlightColor;
- vFrom.size = strlen(appData.premoveHighlightColor);
- XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL) {
- appData.monoMode = True;
- forceMono = True;
- } else {
- premoveHighlightColor = *(Pixel *) vTo.addr;
- }
- }
-
- if (forceMono) {
- fprintf(stderr, "%s: too few colors available; trying monochrome mode\n",
- programName);
- }
-
- if (appData.monoMode && appData.debugMode) {
- fprintf(stderr, "white pixel = 0x%lx, black pixel = 0x%lx\n",
- (unsigned long) XWhitePixel(xDisplay, xScreen),
- (unsigned long) XBlackPixel(xDisplay, xScreen));
- }
-
- if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
- parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
- parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||
- parse_cpair(ColorChannel, appData.colorChannel) < 0 ||
- parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
- parse_cpair(ColorTell, appData.colorTell) < 0 ||
- parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||
- parse_cpair(ColorRequest, appData.colorRequest) < 0 ||
- parse_cpair(ColorSeek, appData.colorSeek) < 0 ||
- parse_cpair(ColorNormal, appData.colorNormal) < 0)
- {
- if (appData.colorize) {
- fprintf(stderr,
- "%s: can't parse color names; disabling colorization\n",
- programName);
- }
- appData.colorize = FALSE;
- }
- textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
- textColors[ColorNone].attr = 0;
-
- XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
-
- /*
- * widget hierarchy
- */
- if (tinyLayout) {
- layoutName = "tinyLayout";
- } else if (smallLayout) {
- layoutName = "smallLayout";
- } else {
- layoutName = "normalLayout";
- }
- /* Outer layoutWidget is there only to provide a name for use in
- resources that depend on the layout style */
- layoutWidget =
- XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
- layoutArgs, XtNumber(layoutArgs));
- formWidget =
- XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
- formArgs, XtNumber(formArgs));
- XtSetArg(args[0], XtNdefaultDistance, &sep);
- XtGetValues(formWidget, args, 1);
-
- j = 0;
- widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
-
- widgetList[j++] = whiteTimerWidget =
- XtCreateWidget("whiteTime", labelWidgetClass,
- formWidget, timerArgs, XtNumber(timerArgs));
- XtSetArg(args[0], XtNfont, clockFontStruct);
- XtSetValues(whiteTimerWidget, args, 1);
-
- widgetList[j++] = blackTimerWidget =
- XtCreateWidget("blackTime", labelWidgetClass,
- formWidget, timerArgs, XtNumber(timerArgs));
- XtSetArg(args[0], XtNfont, clockFontStruct);
- XtSetValues(blackTimerWidget, args, 1);
-
- if (appData.titleInWindow) {
- widgetList[j++] = titleWidget =
- XtCreateWidget("title", labelWidgetClass, formWidget,
- titleArgs, XtNumber(titleArgs));
- }
-
- if (appData.showButtonBar) {
- widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
- }
-
- widgetList[j++] = messageWidget =
- XtCreateWidget("message", labelWidgetClass, formWidget,
- messageArgs, XtNumber(messageArgs));
-
- widgetList[j++] = boardWidget =
- XtCreateWidget("board", widgetClass, formWidget, boardArgs,
- XtNumber(boardArgs));
-
- XtManageChildren(widgetList, j);
-
- timerWidth = (boardWidth - sep) / 2;
- XtSetArg(args[0], XtNwidth, timerWidth);
- XtSetValues(whiteTimerWidget, args, 1);
- XtSetValues(blackTimerWidget, args, 1);
-
- XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
- XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
- XtGetValues(whiteTimerWidget, args, 2);
-
- if (appData.showButtonBar) {
- XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
- XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
- XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
- }
-
- /*
- * formWidget uses these constraints but they are stored
- * in the children.
- */
- i = 0;
- XtSetArg(args[i], XtNfromHoriz, 0); i++;
- XtSetValues(menuBarWidget, args, i);
- if (appData.titleInWindow) {
- if (smallLayout) {
- i = 0;
- XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
- XtSetValues(whiteTimerWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
- XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
- XtSetValues(blackTimerWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
- XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
- XtSetValues(titleWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, titleWidget); i++;
- XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
- XtSetValues(messageWidget, args, i);
- if (appData.showButtonBar) {
- i = 0;
- XtSetArg(args[i], XtNfromVert, titleWidget); i++;
- XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
- XtSetValues(buttonBarWidget, args, i);
- }
- } else {
- i = 0;
- XtSetArg(args[i], XtNfromVert, titleWidget); i++;
- XtSetValues(whiteTimerWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, titleWidget); i++;
- XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
- XtSetValues(blackTimerWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
- XtSetValues(titleWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
- XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
- XtSetValues(messageWidget, args, i);
- if (appData.showButtonBar) {
- i = 0;
- XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
- XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
- XtSetValues(buttonBarWidget, args, i);
- }
- }
- } else {
- i = 0;
- XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
- XtSetValues(whiteTimerWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
- XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
- XtSetValues(blackTimerWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
- XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
- XtSetValues(messageWidget, args, i);
- if (appData.showButtonBar) {
- i = 0;
- XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
- XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
- XtSetValues(buttonBarWidget, args, i);
- }
- }
- i = 0;
- XtSetArg(args[0], XtNfromVert, messageWidget);
- XtSetValues(boardWidget, args, 1);
-
- XtRealizeWidget(shellWidget);
-
- /*
- * Correct the width of the message and title widgets.
- * It is not known why some systems need the extra fudge term.
- * The value "2" is probably larger than needed.
- */
- XawFormDoLayout(formWidget, False);
-#define WIDTH_FUDGE 2
- i = 0;
- XtSetArg(args[i], XtNborderWidth, &bor); i++;
- XtSetArg(args[i], XtNheight, &h); i++;
- XtGetValues(messageWidget, args, i);
- if (appData.showButtonBar) {
- i = 0;
- XtSetArg(args[i], XtNwidth, &w); i++;
- XtGetValues(buttonBarWidget, args, i);
- w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
- } else {
- w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
- }
-
- gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
- if (gres != XtGeometryYes && appData.debugMode) {
- fprintf(stderr, "%s: messageWidget geometry error %d %d %d %d %d\n",
- programName, gres, w, h, wr, hr);
- }
-
- /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
- /* The size used for the child widget in layout lags one resize behind
- its true size, so we resize a second time, 1 pixel smaller. Yeech! */
- w--;
- gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
- if (gres != XtGeometryYes && appData.debugMode) {
- fprintf(stderr, "%s: messageWidget geometry error %d %d %d %d %d\n",
- programName, gres, w, h, wr, hr);
- }
- /* !! end hack */
-
- if (appData.titleInWindow) {
- i = 0;
- XtSetArg(args[i], XtNborderWidth, &bor); i++;
- XtSetArg(args[i], XtNheight, &h); i++;
- XtGetValues(titleWidget, args, i);
- if (smallLayout) {
- w = boardWidth - 2*bor;
- } else {
- XtSetArg(args[0], XtNwidth, &w);
- XtGetValues(menuBarWidget, args, 1);
- w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
- }
-
- gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
- if (gres != XtGeometryYes && appData.debugMode) {
- fprintf(stderr,
- "%s: titleWidget geometry error %d %d %d %d %d\n",
- programName, gres, w, h, wr, hr);
- }
- }
- XawFormDoLayout(formWidget, True);
-
- xBoardWindow = XtWindow(boardWidget);
-
- /*
- * Create X checkmark bitmap and initialize option menu checks.
- */
- ReadBitmap(&xMarkPixmap, "checkmark.bm",
- checkmark_bits, checkmark_width, checkmark_height);
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- if (appData.alwaysPromoteToQueen) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
- args, 1);
- }
- if (appData.animateDragging) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Animate Dragging"),
- args, 1);
- }
- if (appData.animate) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
- args, 1);
- }
- if (appData.autoComment) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
- args, 1);
- }
- if (appData.autoCallFlag) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
- args, 1);
- }
- if (appData.autoFlipView) {
- XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
- args, 1);
- }
- if (appData.autoObserve) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
- args, 1);
- }
- if (appData.autoRaiseBoard) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Auto Raise Board"), args, 1);
- }
- if (appData.autoSaveGames) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
- args, 1);
- }
- if (appData.saveGameFile[0] != NULLCHAR) {
- /* Can't turn this off from menu */
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
- args, 1);
- XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
- False);
-
- }
- if (appData.blindfold) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Blindfold"), args, 1);
- }
- if (appData.flashCount > 0) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Flash Moves"),
- args, 1);
- }
- if (appData.getMoveList) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
- args, 1);
- }
-#if HIGHDRAG
- if (appData.highlightDragging) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Highlight Dragging"),
- args, 1);
- }
-#endif
- if (appData.highlightLastMove) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Highlight Last Move"),
- args, 1);
- }
- if (appData.icsAlarm) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
- args, 1);
- }
- if (appData.ringBellAfterMoves) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
- args, 1);
- }
- if (appData.oldSaveStyle) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Old Save Style"), args, 1);
- }
- if (appData.periodicUpdates) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Periodic Updates"), args, 1);
- }
- if (appData.ponderNextMove) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Ponder Next Move"), args, 1);
- }
- if (appData.popupExitMessage) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Popup Exit Message"), args, 1);
- }
- if (appData.popupMoveErrors) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Popup Move Errors"), args, 1);
- }
- if (appData.premove) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Premove"), args, 1);
- }
- if (appData.quietPlay) {
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Quiet Play"), args, 1);
- }
- if (appData.showCoords) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
- args, 1);
- }
- if (appData.showThinking) {
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
- args, 1);
- }
- if (appData.testLegality) {
- XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
- args, 1);
- }
-
- /*
- * Create an icon.
- */
- ReadBitmap(&wIconPixmap, "icon_white.bm",
- icon_white_bits, icon_white_width, icon_white_height);
- ReadBitmap(&bIconPixmap, "icon_black.bm",
- icon_black_bits, icon_black_width, icon_black_height);
- iconPixmap = wIconPixmap;
- i = 0;
- XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;
- XtSetValues(shellWidget, args, i);
-
- /*
- * Create a cursor for the board widget.
- */
- window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
- XChangeWindowAttributes(xDisplay, xBoardWindow,
- CWCursor, &window_attributes);
-
- /*
- * Inhibit shell resizing.
- */
- shellArgs[0].value = (XtArgVal) &w;
- shellArgs[1].value = (XtArgVal) &h;
- XtGetValues(shellWidget, shellArgs, 2);
- shellArgs[4].value = shellArgs[2].value = w;
- shellArgs[5].value = shellArgs[3].value = h;
- XtSetValues(shellWidget, &shellArgs[2], 4);
-
- CatchDeleteWindow(shellWidget, "QuitProc");
-
- CreateGCs();
- CreateGrid();
-#if HAVE_LIBXPM
- if (appData.bitmapDirectory[0] != NULLCHAR) {
- CreatePieces();
- } else {
- CreateXPMPieces();
- }
-#else
- CreateXIMPieces();
- /* Create regular pieces */
- if (!useImages) CreatePieces();
-#endif
-
- CreatePieceMenus();
-
- if (appData.animate || appData.animateDragging)
- CreateAnimVars();
-
- XtAugmentTranslations(formWidget,
- XtParseTranslationTable(globalTranslations));
- XtAugmentTranslations(boardWidget,
- XtParseTranslationTable(boardTranslations));
- XtAugmentTranslations(whiteTimerWidget,
- XtParseTranslationTable(whiteTranslations));
- XtAugmentTranslations(blackTimerWidget,
- XtParseTranslationTable(blackTranslations));
-
- /* Why is the following needed on some versions of X instead
- * of a translation? */
- XtAddEventHandler(boardWidget, ExposureMask, False,
- (XtEventHandler) EventProc, NULL);
- /* end why */
-
- InitBackEnd2();
-
- if (errorExitStatus == -1) {
- if (appData.icsActive) {
- /* We now wait until we see "login:" from the ICS before
- sending the logon script (problems with timestamp otherwise) */
- /*ICSInitScript();*/
- if (appData.icsInputBox) ICSInputBoxPopUp();
- }
-
- signal(SIGINT, IntSigHandler);
- signal(SIGTERM, IntSigHandler);
- if (*appData.cmailGameName != NULLCHAR) {
- signal(SIGUSR1, CmailSigHandler);
- }
- }
-
- XtAppMainLoop(appContext);
- return 0;
-}
-
-void
-ShutDownFrontEnd()
-{
- if (appData.icsActive && oldICSInteractionTitle != NULL) {
- DisplayIcsInteractionTitle(oldICSInteractionTitle);
- }
- unlink(gameCopyFilename);
- unlink(gamePasteFilename);
-}
-
-RETSIGTYPE
-IntSigHandler(sig)
- int sig;
-{
- ExitEvent(sig);
-}
-
-RETSIGTYPE
-CmailSigHandler(sig)
- int sig;
-{
- int dummy = 0;
- int error;
-
- signal(SIGUSR1, SIG_IGN); /* suspend handler */
-
- /* Activate call-back function CmailSigHandlerCallBack() */
- OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
-
- signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
-}
-
-void
-CmailSigHandlerCallBack(isr, closure, message, count, error)
- InputSourceRef isr;
- VOIDSTAR closure;
- char *message;
- int count;
- int error;
-{
- BoardToTop();
- ReloadCmailMsgEvent(TRUE); /* Reload cmail msg */
-}
-/**** end signal code ****/
-
-
-void
-ICSInitScript()
-{
- FILE *f;
- char buf[MSG_SIZ];
- char *p;
-
- f = fopen(appData.icsLogon, "r");
- if (f == NULL) {
- p = getenv("HOME");
- if (p != NULL) {
- strcpy(buf, p);
- strcat(buf, "/");
- strcat(buf, appData.icsLogon);
- f = fopen(buf, "r");
- }
- }
- if (f != NULL)
- ProcessICSInitScript(f);
-}
-
-void
-ResetFrontEnd()
-{
- CommentPopDown();
- EditCommentPopDown();
- TagsPopDown();
- return;
-}
-
-typedef struct {
- char *name;
- Boolean value;
-} Enables;
-
-void
-SetMenuEnables(enab)
- Enables *enab;
-{
- Widget w;
- if (!menuBarWidget) return;
- while (enab->name != NULL) {
- w = XtNameToWidget(menuBarWidget, enab->name);
- if (w == NULL) {
- DisplayError(enab->name, 0);
- } else {
- XtSetSensitive(w, enab->value);
- }
- enab++;
- }
-}
-
-Enables icsEnables[] = {
- { "menuFile.Mail Move", False },
- { "menuFile.Reload CMail Message", False },
- { "menuMode.Machine Black", False },
- { "menuMode.Machine White", False },
- { "menuMode.Analysis Mode", False },
- { "menuMode.Analyze File", False },
- { "menuMode.Two Machines", False },
-#ifndef ZIPPY
- { "menuHelp.Hint", False },
- { "menuHelp.Book", False },
- { "menuStep.Move Now", False },
- { "menuOptions.Periodic Updates", False },
- { "menuOptions.Show Thinking", False },
- { "menuOptions.Ponder Next Move", False },
-#endif
- { NULL, False }
-};
-
-Enables ncpEnables[] = {
- { "menuFile.Mail Move", False },
- { "menuFile.Reload CMail Message", False },
- { "menuMode.Machine White", False },
- { "menuMode.Machine Black", False },
- { "menuMode.Analysis Mode", False },
- { "menuMode.Analyze File", False },
- { "menuMode.Two Machines", False },
- { "menuMode.ICS Client", False },
- { "menuMode.ICS Input Box", False },
- { "Action", False },
- { "menuStep.Revert", False },
- { "menuStep.Move Now", False },
- { "menuStep.Retract Move", False },
- { "menuOptions.Auto Comment", False },
- { "menuOptions.Auto Flag", False },
- { "menuOptions.Auto Flip View", False },
- { "menuOptions.Auto Observe", False },
- { "menuOptions.Auto Raise Board", False },
- { "menuOptions.Get Move List", False },
- { "menuOptions.ICS Alarm", False },
- { "menuOptions.Move Sound", False },
- { "menuOptions.Quiet Play", False },
- { "menuOptions.Show Thinking", False },
- { "menuOptions.Periodic Updates", False },
- { "menuOptions.Ponder Next Move", False },
- { "menuHelp.Hint", False },
- { "menuHelp.Book", False },
- { NULL, False }
-};
-
-Enables gnuEnables[] = {
- { "menuMode.ICS Client", False },
- { "menuMode.ICS Input Box", False },
- { "menuAction.Accept", False },
- { "menuAction.Decline", False },
- { "menuAction.Rematch", False },
- { "menuAction.Adjourn", False },
- { "menuAction.Stop Examining", False },
- { "menuAction.Stop Observing", False },
- { "menuStep.Revert", False },
- { "menuOptions.Auto Comment", False },
- { "menuOptions.Auto Observe", False },
- { "menuOptions.Auto Raise Board", False },
- { "menuOptions.Get Move List", False },
- { "menuOptions.Premove", False },
- { "menuOptions.Quiet Play", False },
-
- /* The next two options rely on SetCmailMode being called *after* */
- /* SetGNUMode so that when GNU is being used to give hints these */
- /* menu options are still available */
-
- { "menuFile.Mail Move", False },
- { "menuFile.Reload CMail Message", False },
- { NULL, False }
-};
-
-Enables cmailEnables[] = {
- { "Action", True },
- { "menuAction.Call Flag", False },
- { "menuAction.Draw", True },
- { "menuAction.Adjourn", False },
- { "menuAction.Abort", False },
- { "menuAction.Stop Observing", False },
- { "menuAction.Stop Examining", False },
- { "menuFile.Mail Move", True },
- { "menuFile.Reload CMail Message", True },
- { NULL, False }
-};
-
-Enables trainingOnEnables[] = {
- { "menuMode.Edit Comment", False },
- { "menuMode.Pause", False },
- { "menuStep.Forward", False },
- { "menuStep.Backward", False },
- { "menuStep.Forward to End", False },
- { "menuStep.Back to Start", False },
- { "menuStep.Move Now", False },
- { "menuStep.Truncate Game", False },
- { NULL, False }
-};
-
-Enables trainingOffEnables[] = {
- { "menuMode.Edit Comment", True },
- { "menuMode.Pause", True },
- { "menuStep.Forward", True },
- { "menuStep.Backward", True },
- { "menuStep.Forward to End", True },
- { "menuStep.Back to Start", True },
- { "menuStep.Move Now", True },
- { "menuStep.Truncate Game", True },
- { NULL, False }
-};
-
-Enables machineThinkingEnables[] = {
- { "menuFile.Load Game", False },
- { "menuFile.Load Next Game", False },
- { "menuFile.Load Previous Game", False },
- { "menuFile.Reload Same Game", False },
- { "menuFile.Paste Game", False },
- { "menuFile.Load Position", False },
- { "menuFile.Load Next Position", False },
- { "menuFile.Load Previous Position", False },
- { "menuFile.Reload Same Position", False },
- { "menuFile.Paste Position", False },
- { "menuMode.Machine White", False },
- { "menuMode.Machine Black", False },
- { "menuMode.Two Machines", False },
- { "menuStep.Retract Move", False },
- { NULL, False }
-};
-
-Enables userThinkingEnables[] = {
- { "menuFile.Load Game", True },
- { "menuFile.Load Next Game", True },
- { "menuFile.Load Previous Game", True },
- { "menuFile.Reload Same Game", True },
- { "menuFile.Paste Game", True },
- { "menuFile.Load Position", True },
- { "menuFile.Load Next Position", True },
- { "menuFile.Load Previous Position", True },
- { "menuFile.Reload Same Position", True },
- { "menuFile.Paste Position", True },
- { "menuMode.Machine White", True },
- { "menuMode.Machine Black", True },
- { "menuMode.Two Machines", True },
- { "menuStep.Retract Move", True },
- { NULL, False }
-};
-
-void SetICSMode()
-{
- SetMenuEnables(icsEnables);
-}
-
-void
-SetNCPMode()
-{
- SetMenuEnables(ncpEnables);
-}
-
-void
-SetGNUMode()
-{
- SetMenuEnables(gnuEnables);
-}
-
-void
-SetCmailMode()
-{
- SetMenuEnables(cmailEnables);
-}
-
-void
-SetTrainingModeOn()
-{
- SetMenuEnables(trainingOnEnables);
- if (appData.showButtonBar) {
- XtSetSensitive(buttonBarWidget, False);
- }
- CommentPopDown();
-}
-
-void
-SetTrainingModeOff()
-{
- SetMenuEnables(trainingOffEnables);
- if (appData.showButtonBar) {
- XtSetSensitive(buttonBarWidget, True);
- }
-}
-
-void
-SetUserThinkingEnables()
-{
- if (appData.noChessProgram) return;
- SetMenuEnables(userThinkingEnables);
-}
-
-void
-SetMachineThinkingEnables()
-{
- if (appData.noChessProgram) return;
- SetMenuEnables(machineThinkingEnables);
- switch (gameMode) {
- case MachinePlaysBlack:
- case MachinePlaysWhite:
- case TwoMachinesPlay:
- XtSetSensitive(XtNameToWidget(menuBarWidget,
- ModeToWidgetName(gameMode)), True);
- break;
- default:
- break;
- }
-}
-
-#define Abs(n) ((n)<0 ? -(n) : (n))
-
-/*
- * Find a font that matches "pattern" that is as close as
- * possible to the targetPxlSize. Prefer fonts that are k
- * pixels smaller to fonts that are k pixels larger. The
- * pattern must be in the X Consortium standard format,
- * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
- * The return value should be freed with XtFree when no
- * longer needed.
- */
-char *FindFont(pattern, targetPxlSize)
- char *pattern;
- int targetPxlSize;
-{
- char **fonts, *p, *best, *scalable, *scalableTail;
- int i, j, nfonts, minerr, err, pxlSize;
-
- fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
- if (nfonts < 1) {
- fprintf(stderr, "%s: no fonts match pattern %s\n",
- programName, pattern);
- exit(2);
- }
- best = fonts[0];
- scalable = NULL;
- minerr = 999999;
- for (i=0; i<nfonts; i++) {
- j = 0;
- p = fonts[i];
- if (*p != '-') continue;
- while (j < 7) {
- if (*p == NULLCHAR) break;
- if (*p++ == '-') j++;
- }
- if (j < 7) continue;
- pxlSize = atoi(p);
- if (pxlSize == 0) {
- scalable = fonts[i];
- scalableTail = p;
- } else {
- err = pxlSize - targetPxlSize;
- if (Abs(err) < Abs(minerr) ||
- (minerr > 0 && err < 0 && -err == minerr)) {
- best = fonts[i];
- minerr = err;
- }
- }
- }
- if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
- /* If the error is too big and there is a scalable font,
- use the scalable font. */
- int headlen = scalableTail - scalable;
- p = (char *) XtMalloc(strlen(scalable) + 10);
- while (isdigit(*scalableTail)) scalableTail++;
- sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
- } else {
- p = (char *) XtMalloc(strlen(best) + 1);
- strcpy(p, best);
- }
- if (appData.debugMode) {
- fprintf(debugFP, "resolved %s at pixel size %d\n to %s\n",
- pattern, targetPxlSize, p);
- }
- XFreeFontNames(fonts);
- return p;
-}
-
-void CreateGCs()
-{
- XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
- | GCBackground | GCFunction | GCPlaneMask;
- XGCValues gc_values;
- GC copyInvertedGC;
-
- gc_values.plane_mask = AllPlanes;
- gc_values.line_width = lineGap;
- gc_values.line_style = LineSolid;
- gc_values.function = GXcopy;
-
- gc_values.foreground = XBlackPixel(xDisplay, xScreen);
- gc_values.background = XBlackPixel(xDisplay, xScreen);
- lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = XBlackPixel(xDisplay, xScreen);
- gc_values.background = XWhitePixel(xDisplay, xScreen);
- coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
- XSetFont(xDisplay, coordGC, coordFontID);
-
- if (appData.monoMode) {
- gc_values.foreground = XWhitePixel(xDisplay, xScreen);
- gc_values.background = XWhitePixel(xDisplay, xScreen);
- highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = XWhitePixel(xDisplay, xScreen);
- gc_values.background = XBlackPixel(xDisplay, xScreen);
- lightSquareGC = wbPieceGC
- = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = XBlackPixel(xDisplay, xScreen);
- gc_values.background = XWhitePixel(xDisplay, xScreen);
- darkSquareGC = bwPieceGC
- = XtGetGC(shellWidget, value_mask, &gc_values);
-
- if (DefaultDepth(xDisplay, xScreen) == 1) {
- /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
- gc_values.function = GXcopyInverted;
- copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
- gc_values.function = GXcopy;
- if (XBlackPixel(xDisplay, xScreen) == 1) {
- bwPieceGC = darkSquareGC;
- wbPieceGC = copyInvertedGC;
- } else {
- bwPieceGC = copyInvertedGC;
- wbPieceGC = lightSquareGC;
- }
- }
- } else {
- gc_values.foreground = highlightSquareColor;
- gc_values.background = highlightSquareColor;
- highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = premoveHighlightColor;
- gc_values.background = premoveHighlightColor;
- prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = lightSquareColor;
- gc_values.background = darkSquareColor;
- lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = darkSquareColor;
- gc_values.background = lightSquareColor;
- darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = jailSquareColor;
- gc_values.background = jailSquareColor;
- jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = whitePieceColor;
- gc_values.background = darkSquareColor;
- wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = whitePieceColor;
- gc_values.background = lightSquareColor;
- wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = whitePieceColor;
- gc_values.background = jailSquareColor;
- wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = blackPieceColor;
- gc_values.background = darkSquareColor;
- bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = blackPieceColor;
- gc_values.background = lightSquareColor;
- blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
-
- gc_values.foreground = blackPieceColor;
- gc_values.background = jailSquareColor;
- bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
- }
-}
-
-void loadXIM(xim, xmask, filename, dest, mask)
- XImage *xim;
- XImage *xmask;
- char *filename;
- Pixmap *dest;
- Pixmap *mask;
-{
- int x, y, w, h, p;
- FILE *fp;
- Pixmap temp;
- XGCValues values;
- GC maskGC;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "%s: error loading XIM!\n", programName);
- exit(1);
- }
-
- w = fgetc(fp);
- h = fgetc(fp);
-
- for (y=0; y<h; ++y) {
- for (x=0; x<h; ++x) {
- p = fgetc(fp);
-
- switch (p) {
- case 0:
- XPutPixel(xim, x, y, blackPieceColor);
- if (xmask)
- XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
- break;
- case 1:
- XPutPixel(xim, x, y, darkSquareColor);
- if (xmask)
- XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
- break;
- case 2:
- XPutPixel(xim, x, y, whitePieceColor);
- if (xmask)
- XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
- break;
- case 3:
- XPutPixel(xim, x, y, lightSquareColor);
- if (xmask)
- XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
- break;
- }
- }
- }
-
- /* create Pixmap of piece */
- *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
- w, h, xim->depth);
- XPutImage(xDisplay, *dest, lightSquareGC, xim,
- 0, 0, 0, 0, w, h);
-
- /* create Pixmap of clipmask
- Note: We assume the white/black pieces have the same
- outline, so we make only 6 masks. This is okay
- since the XPM clipmask routines do the same. */
- if (xmask) {
- temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
- w, h, xim->depth);
- XPutImage(xDisplay, temp, lightSquareGC, xmask,
- 0, 0, 0, 0, w, h);
-
- /* now create the 1-bit version */
- *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
- w, h, 1);
-
- values.foreground = 1;
- values.background = 0;
-
- /* Don't use XtGetGC, not read only */
- maskGC = XCreateGC(xDisplay, *mask,
- GCForeground | GCBackground, &values);
- XCopyPlane(xDisplay, temp, *mask, maskGC,
- 0, 0, squareSize, squareSize, 0, 0, 1);
- XFreePixmap(xDisplay, temp);
- }
-}
-
-void CreateXIMPieces()
-{
- int piece, kind;
- char buf[MSG_SIZ];
- u_int ss;
- static char *ximkind[] = { "ll", "ld", "dl", "dd" };
- XImage *ximtemp;
-
- ss = squareSize;
-
- /* The XSynchronize calls were copied from CreatePieces.
- Not sure if needed, but can't hurt */
- XSynchronize(xDisplay, True); /* Work-around for xlib/xt
- buffering bug */
-
- /* temp needed by loadXIM() */
- ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
- 0, 0, ss, ss, AllPlanes, XYPixmap);
-
- if (strlen(appData.pixmapDirectory) == 0) {
- useImages = 0;
- } else {
- useImages = 1;
- if (appData.monoMode) {
- DisplayFatalError("XIM pieces cannot be used in monochrome mode",
- 0, 2);
- ExitEvent(2);
- }
- fprintf(stderr, "\nLoading XIMs...\n");
- /* Load pieces */
- for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
- fprintf(stderr, "%d", piece+1);
- for (kind=0; kind<4; kind++) {
- fprintf(stderr, ".");
- sprintf(buf, "%s/%c%s%u.xim",
- ExpandPathName(appData.pixmapDirectory),
- ToLower(PieceToChar((ChessSquare)piece)),
- ximkind[kind], ss);
- ximPieceBitmap[kind][piece] =
- XGetImage(xDisplay, DefaultRootWindow(xDisplay),
- 0, 0, ss, ss, AllPlanes, XYPixmap);
- if (appData.debugMode)
- fprintf(stderr, "(File:%s:) ", buf);
- loadXIM(ximPieceBitmap[kind][piece],
- ximtemp, buf,
- &(xpmPieceBitmap[kind][piece]),
- &(ximMaskPm[piece%6]));
- }
- fprintf(stderr," ");
- }
- /* Load light and dark squares */
- /* If the LSQ and DSQ pieces don't exist, we will
- draw them with solid squares. */
- sprintf(buf, "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
- if (access(buf, 0) != 0) {
- useImageSqs = 0;
- } else {
- useImageSqs = 1;
- fprintf(stderr, "light square ");
- ximLightSquare=
- XGetImage(xDisplay, DefaultRootWindow(xDisplay),
- 0, 0, ss, ss, AllPlanes, XYPixmap);
- if (appData.debugMode)
- fprintf(stderr, "(File:%s:) ", buf);
-
- loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
- fprintf(stderr, "dark square ");
- sprintf(buf, "%s/dsq%u.xim",
- ExpandPathName(appData.pixmapDirectory), ss);
- if (appData.debugMode)
- fprintf(stderr, "(File:%s:) ", buf);
- ximDarkSquare=
- XGetImage(xDisplay, DefaultRootWindow(xDisplay),
- 0, 0, ss, ss, AllPlanes, XYPixmap);
- loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
- xpmJailSquare = xpmLightSquare;
- }
- fprintf(stderr, "Done.\n");
- }
- XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
-}
-
-#if HAVE_LIBXPM
-void CreateXPMPieces()
-{
- int piece, kind, r;
- char buf[MSG_SIZ];
- u_int ss = squareSize;
- XpmAttributes attr;
- static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
- XpmColorSymbol symbols[4];
-
-#if 0
- /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
- if (appData.debugMode) {
- fprintf(stderr, "XPM Library Version: %d.%d%c\n",
- XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
- }
-#endif
-
- /* The XSynchronize calls were copied from CreatePieces.
- Not sure if needed, but can't hurt */
- XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
-
- /* Setup translations so piece colors match square colors */
- symbols[0].name = "light_piece";
- symbols[0].value = appData.whitePieceColor;
- symbols[1].name = "dark_piece";
- symbols[1].value = appData.blackPieceColor;
- symbols[2].name = "light_square";
- symbols[2].value = appData.lightSquareColor;
- symbols[3].name = "dark_square";
- symbols[3].value = appData.darkSquareColor;
-
- attr.valuemask = XpmColorSymbols;
- attr.colorsymbols = symbols;
- attr.numsymbols = 4;
-
- if (appData.monoMode) {
- DisplayFatalError("XPM pieces cannot be used in monochrome mode",
- 0, 2);
- ExitEvent(2);
- }
- if (strlen(appData.pixmapDirectory) == 0) {
- XpmPieces* pieces = builtInXpms;
- useImages = 1;
- /* Load pieces */
- while (pieces->size != squareSize && pieces->size) pieces++;
- if (!pieces->size) {
- fprintf(stderr, "No builtin XPM pieces of size %d\n", squareSize);
- exit(1);
- }
- for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
- for (kind=0; kind<4; kind++) {
-
- if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
- pieces->xpm[piece][kind],
- &(xpmPieceBitmap[kind][piece]),
- NULL, &attr)) != 0) {
- fprintf(stderr, "Error %d loading XPM image \"%s\"\n",
- r, buf);
- exit(1);
- }
- }
- }
- useImageSqs = 0;
- xpmJailSquare = xpmLightSquare;
- } else {
- useImages = 1;
-
- fprintf(stderr, "\nLoading XPMs...\n");
-
- /* Load pieces */
- for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
- fprintf(stderr, "%d ", piece+1);
- for (kind=0; kind<4; kind++) {
- sprintf(buf, "%s/%c%s%u.xpm",
- ExpandPathName(appData.pixmapDirectory),
- ToLower(PieceToChar((ChessSquare)piece)),
- xpmkind[kind], ss);
- if (appData.debugMode) {
- fprintf(stderr, "(File:%s:) ", buf);
- }
- if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
- &(xpmPieceBitmap[kind][piece]),
- NULL, &attr)) != 0) {
- fprintf(stderr, "Error %d loading XPM file \"%s\"\n",
- r, buf);
- exit(1);
- }
- }
- }
- /* Load light and dark squares */
- /* If the LSQ and DSQ pieces don't exist, we will
- draw them with solid squares. */
- fprintf(stderr, "light square ");
- sprintf(buf, "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
- if (access(buf, 0) != 0) {
- useImageSqs = 0;
- } else {
- useImageSqs = 1;
- if (appData.debugMode)
- fprintf(stderr, "(File:%s:) ", buf);
-
- if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
- &xpmLightSquare, NULL, &attr)) != 0) {
- fprintf(stderr, "Error %d loading XPM file \"%s\"\n", r, buf);
- exit(1);
- }
- fprintf(stderr, "dark square ");
- sprintf(buf, "%s/dsq%u.xpm",
- ExpandPathName(appData.pixmapDirectory), ss);
- if (appData.debugMode) {
- fprintf(stderr, "(File:%s:) ", buf);
- }
- if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
- &xpmDarkSquare, NULL, &attr)) != 0) {
- fprintf(stderr, "Error %d loading XPM file \"%s\"\n", r, buf);
- exit(1);
- }
- }
- xpmJailSquare = xpmLightSquare;
- fprintf(stderr, "Done.\n");
- }
- XSynchronize(xDisplay, False); /* Work-around for xlib/xt
- buffering bug */
-}
-#endif /* HAVE_LIBXPM */
-
-#if HAVE_LIBXPM
-/* No built-in bitmaps */
-void CreatePieces()
-{
- int piece, kind;
- char buf[MSG_SIZ];
- u_int ss = squareSize;
-
- XSynchronize(xDisplay, True); /* Work-around for xlib/xt
- buffering bug */
-
- for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
- for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
- sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
- ss, kind == SOLID ? 's' : 'o');
- ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);
- }
- }
-
- XSynchronize(xDisplay, False); /* Work-around for xlib/xt
- buffering bug */
-}
-#else
-/* With built-in bitmaps */
-void CreatePieces()
-{
- BuiltInBits* bib = builtInBits;
- int piece, kind;
- char buf[MSG_SIZ];
- u_int ss = squareSize;
-
- XSynchronize(xDisplay, True); /* Work-around for xlib/xt
- buffering bug */
-
- while (bib->squareSize != ss && bib->squareSize != 0) bib++;
-
- for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
- for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
- sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
- ss, kind == SOLID ? 's' : 'o');
- ReadBitmap(&pieceBitmap[kind][piece], buf,
- bib->bits[kind][piece], ss, ss);
- }
- }
-
- XSynchronize(xDisplay, False); /* Work-around for xlib/xt
- buffering bug */
-}
-#endif
-
-void ReadBitmap(pm, name, bits, wreq, hreq)
- Pixmap *pm;
- String name;
- unsigned char bits[];
- u_int wreq, hreq;
-{
- int x_hot, y_hot;
- u_int w, h;
- int errcode;
- char msg[MSG_SIZ], fullname[MSG_SIZ];
-
- if (*appData.bitmapDirectory != NULLCHAR) {
- strcpy(fullname, appData.bitmapDirectory);
- strcat(fullname, "/");
- strcat(fullname, name);
- errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
- &w, &h, pm, &x_hot, &y_hot);
- if (errcode != BitmapSuccess) {
- switch (errcode) {
- case BitmapOpenFailed:
- sprintf(msg, "Can't open bitmap file %s", fullname);
- break;
- case BitmapFileInvalid:
- sprintf(msg, "Invalid bitmap in file %s", fullname);
- break;
- case BitmapNoMemory:
- sprintf(msg, "Ran out of memory reading bitmap file %s",
- fullname);
- break;
- default:
- sprintf(msg, "Unknown XReadBitmapFile error %d on file %s",
- errcode, fullname);
- break;
- }
- fprintf(stderr, "%s: %s...using built-in\n",
- programName, msg);
- } else if (w != wreq || h != hreq) {
- fprintf(stderr,
- "%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n",
- programName, fullname, w, h, wreq, hreq);
- } else {
- return;
- }
- }
- if (bits == NULL) {
- fprintf(stderr, "%s: No built-in bitmap for %s; giving up\n",
- programName, name);
- exit(1);
- } else {
- *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
- wreq, hreq);
- }
-}
-
-void CreateGrid()
-{
- int i;
-
- if (lineGap == 0) return;
- for (i = 0; i < BOARD_SIZE + 1; i++) {
- gridSegments[i].x1 = 0;
- gridSegments[i].x2 =
- lineGap + BOARD_SIZE * (squareSize + lineGap);
- gridSegments[i].y1 = gridSegments[i].y2
- = lineGap / 2 + (i * (squareSize + lineGap));
-
- gridSegments[i + BOARD_SIZE + 1].y1 = 0;
- gridSegments[i + BOARD_SIZE + 1].y2 =
- BOARD_SIZE * (squareSize + lineGap);
- gridSegments[i + BOARD_SIZE + 1].x1 =
- gridSegments[i + BOARD_SIZE + 1].x2
- = lineGap / 2 + (i * (squareSize + lineGap));
- }
-}
-
-static void MenuBarSelect(w, addr, index)
- Widget w;
- caddr_t addr;
- caddr_t index;
-{
- XtActionProc proc = (XtActionProc) addr;
-
- (proc)(NULL, NULL, NULL, NULL);
-}
-
-void CreateMenuBarPopup(parent, name, mb)
- Widget parent;
- String name;
- Menu *mb;
-{
- int j;
- Widget menu, entry;
- MenuItem *mi;
- Arg args[16];
-
- menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
- parent, NULL, 0);
- j = 0;
- XtSetArg(args[j], XtNleftMargin, 20); j++;
- XtSetArg(args[j], XtNrightMargin, 20); j++;
- mi = mb->mi;
- while (mi->string != NULL) {
- if (strcmp(mi->string, "----") == 0) {
- entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
- menu, args, j);
- } else {
- entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
- menu, args, j);
- XtAddCallback(entry, XtNcallback,
- (XtCallbackProc) MenuBarSelect,
- (caddr_t) mi->proc);
- }
- mi++;
- }
-}
-
-Widget CreateMenuBar(mb)
- Menu *mb;
-{
- int j;
- Widget anchor, menuBar;
- Arg args[16];
- char menuName[MSG_SIZ];
-
- j = 0;
- XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
- XtSetArg(args[j], XtNvSpace, 0); j++;
- XtSetArg(args[j], XtNborderWidth, 0); j++;
- menuBar = XtCreateWidget("menuBar", boxWidgetClass,
- formWidget, args, j);
-
- while (mb->name != NULL) {
- strcpy(menuName, "menu");
- strcat(menuName, mb->name);
- j = 0;
- XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;
- if (tinyLayout) {
- char shortName[2];
- shortName[0] = mb->name[0];
- shortName[1] = NULLCHAR;
- XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
- }
- XtSetArg(args[j], XtNborderWidth, 0); j++;
- anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
- menuBar, args, j);
- CreateMenuBarPopup(menuBar, menuName, mb);
- mb++;
- }
- return menuBar;
-}
-
-Widget CreateButtonBar(mi)
- MenuItem *mi;
-{
- int j;
- Widget button, buttonBar;
- Arg args[16];
-
- j = 0;
- XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
- if (tinyLayout) {
- XtSetArg(args[j], XtNhSpace, 0); j++;
- }
- XtSetArg(args[j], XtNborderWidth, 0); j++;
- XtSetArg(args[j], XtNvSpace, 0); j++;
- buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
- formWidget, args, j);
-
- while (mi->string != NULL) {
- j = 0;
- if (tinyLayout) {
- XtSetArg(args[j], XtNinternalWidth, 2); j++;
- XtSetArg(args[j], XtNborderWidth, 0); j++;
- }
- button = XtCreateManagedWidget(mi->string, commandWidgetClass,
- buttonBar, args, j);
- XtAddCallback(button, XtNcallback,
- (XtCallbackProc) MenuBarSelect,
- (caddr_t) mi->proc);
- mi++;
- }
- return buttonBar;
-}
-
-Widget
-CreatePieceMenu(name, color)
- char *name;
- int color;
-{
- int i;
- Widget entry, menu;
- Arg args[16];
- ChessSquare selection;
-
- menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
- boardWidget, args, 0);
-
- for (i = 0; i < PIECE_MENU_SIZE; i++) {
- String item = pieceMenuStrings[color][i];
-
- if (strcmp(item, "----") == 0) {
- entry = XtCreateManagedWidget(item, smeLineObjectClass,
- menu, NULL, 0);
- } else {
- entry = XtCreateManagedWidget(item, smeBSBObjectClass,
- menu, NULL, 0);
- selection = pieceMenuTranslation[color][i];
- XtAddCallback(entry, XtNcallback,
- (XtCallbackProc) PieceMenuSelect,
- (caddr_t) selection);
- if (selection == WhitePawn || selection == BlackPawn) {
- XtSetArg(args[0], XtNpopupOnEntry, entry);
- XtSetValues(menu, args, 1);
- }
- }
- }
- return menu;
-}
-
-void
-CreatePieceMenus()
-{
- int i;
- Widget entry;
- Arg args[16];
- ChessSquare selection;
-
- whitePieceMenu = CreatePieceMenu("menuW", 0);
- blackPieceMenu = CreatePieceMenu("menuB", 1);
-
- XtRegisterGrabAction(PieceMenuPopup, True,
- (unsigned)(ButtonPressMask|ButtonReleaseMask),
- GrabModeAsync, GrabModeAsync);
-
- XtSetArg(args[0], XtNlabel, "Drop");
- dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
- boardWidget, args, 1);
- for (i = 0; i < DROP_MENU_SIZE; i++) {
- String item = dropMenuStrings[i];
-
- if (strcmp(item, "----") == 0) {
- entry = XtCreateManagedWidget(item, smeLineObjectClass,
- dropMenu, NULL, 0);
- } else {
- entry = XtCreateManagedWidget(item, smeBSBObjectClass,
- dropMenu, NULL, 0);
- selection = dropMenuTranslation[i];
- XtAddCallback(entry, XtNcallback,
- (XtCallbackProc) DropMenuSelect,
- (caddr_t) selection);
- }
- }
-}
-
-void SetupDropMenu()
-{
- int i, j, count;
- char label[32];
- Arg args[16];
- Widget entry;
- char* p;
-
- for (i=0; i<sizeof(dmEnables)/sizeof(DropMenuEnables); i++) {
- entry = XtNameToWidget(dropMenu, dmEnables[i].widget);
- p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,
- dmEnables[i].piece);
- XtSetSensitive(entry, p != NULL || !appData.testLegality
- /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse
- && !appData.icsActive));
- count = 0;
- while (p && *p++ == dmEnables[i].piece) count++;
- sprintf(label, "%s %d", dmEnables[i].widget, count);
- j = 0;
- XtSetArg(args[j], XtNlabel, label); j++;
- XtSetValues(entry, args, j);
- }
-}
-
-void PieceMenuPopup(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
-{
- String whichMenu;
- if (event->type != ButtonPress) return;
- if (errorUp) ErrorPopDown();
- switch (gameMode) {
- case EditPosition:
- case IcsExamining:
- whichMenu = params[0];
- break;
- case IcsPlayingWhite:
- case IcsPlayingBlack:
- case EditGame:
- case MachinePlaysWhite:
- case MachinePlaysBlack:
- if (appData.testLegality &&
- gameInfo.variant != VariantBughouse &&
- gameInfo.variant != VariantCrazyhouse) return;
- SetupDropMenu();
- whichMenu = "menuD";
- break;
- default:
- return;
- }
-
- if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_SIZE)) < 0) ||
- ((pmFromY = EventToSquare(event->xbutton.y, BOARD_SIZE)) < 0)) {
- pmFromX = pmFromY = -1;
- return;
- }
- if (flipView)
- pmFromX = BOARD_SIZE - 1 - pmFromX;
- else
- pmFromY = BOARD_SIZE - 1 - pmFromY;
-
- XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
-}
-
-static void PieceMenuSelect(w, piece, junk)
- Widget w;
- ChessSquare piece;
- caddr_t junk;
-{
- if (pmFromX < 0 || pmFromY < 0) return;
- EditPositionMenuEvent(piece, pmFromX, pmFromY);
-}
-
-static void DropMenuSelect(w, piece, junk)
- Widget w;
- ChessSquare piece;
- caddr_t junk;
-{
- if (pmFromX < 0 || pmFromY < 0) return;
- DropMenuEvent(piece, pmFromX, pmFromY);
-}
-
-void WhiteClock(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (gameMode == EditPosition || gameMode == IcsExamining) {
- SetWhiteToPlayEvent();
- } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
- CallFlagEvent();
- }
-}
-
-void BlackClock(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (gameMode == EditPosition || gameMode == IcsExamining) {
- SetBlackToPlayEvent();
- } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
- CallFlagEvent();
- }
-}
-
-
-/*
- * If the user selects on a border boundary, return -1; if off the board,
- * return -2. Otherwise map the event coordinate to the square.
- */
-int EventToSquare(x, limit)
- int x;
-{
- if (x <= 0)
- return -2;
- if (x < lineGap)
- return -1;
- x -= lineGap;
- if ((x % (squareSize + lineGap)) >= squareSize)
- return -1;
- x /= (squareSize + lineGap);
- if (x >= limit)
- return -2;
- return x;
-}
-
-static void do_flash_delay(msec)
- unsigned long msec;
-{
- TimeDelay(msec);
-}
-
-static void drawHighlight(file, rank, gc)
- int file, rank;
- GC gc;
-{
- int x, y;
-
- if (lineGap == 0 || appData.blindfold) return;
-
- if (flipView) {
- x = lineGap/2 + ((BOARD_SIZE-1)-file) *
- (squareSize + lineGap);
- y = lineGap/2 + rank * (squareSize + lineGap);
- } else {
- x = lineGap/2 + file * (squareSize + lineGap);
- y = lineGap/2 + ((BOARD_SIZE-1)-rank) *
- (squareSize + lineGap);
- }
-
- XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
- squareSize+lineGap, squareSize+lineGap);
-}
-
-int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
-int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1;
-
-void
-SetHighlights(fromX, fromY, toX, toY)
- int fromX, fromY, toX, toY;
-{
- if (hi1X != fromX || hi1Y != fromY) {
- if (hi1X >= 0 && hi1Y >= 0) {
- drawHighlight(hi1X, hi1Y, lineGC);
- }
- if (fromX >= 0 && fromY >= 0) {
- drawHighlight(fromX, fromY, highlineGC);
- }
- }
- if (hi2X != toX || hi2Y != toY) {
- if (hi2X >= 0 && hi2Y >= 0) {
- drawHighlight(hi2X, hi2Y, lineGC);
- }
- if (toX >= 0 && toY >= 0) {
- drawHighlight(toX, toY, highlineGC);
- }
- }
- hi1X = fromX;
- hi1Y = fromY;
- hi2X = toX;
- hi2Y = toY;
-}
-
-void
-ClearHighlights()
-{
- SetHighlights(-1, -1, -1, -1);
-}
-
-
-void
-SetPremoveHighlights(fromX, fromY, toX, toY)
- int fromX, fromY, toX, toY;
-{
- if (pm1X != fromX || pm1Y != fromY) {
- if (pm1X >= 0 && pm1Y >= 0) {
- drawHighlight(pm1X, pm1Y, lineGC);
- }
- if (fromX >= 0 && fromY >= 0) {
- drawHighlight(fromX, fromY, prelineGC);
- }
- }
- if (pm2X != toX || pm2Y != toY) {
- if (pm2X >= 0 && pm2Y >= 0) {
- drawHighlight(pm2X, pm2Y, lineGC);
- }
- if (toX >= 0 && toY >= 0) {
- drawHighlight(toX, toY, prelineGC);
- }
- }
- pm1X = fromX;
- pm1Y = fromY;
- pm2X = toX;
- pm2Y = toY;
-}
-
-void
-ClearPremoveHighlights()
-{
- SetPremoveHighlights(-1, -1, -1, -1);
-}
-
-static void BlankSquare(x, y, color, piece, dest)
- int x, y, color;
- ChessSquare piece;
- Drawable dest;
-{
- if (useImages && useImageSqs) {
- Pixmap pm;
- switch (color) {
- case 1: /* light */
- pm = xpmLightSquare;
- break;
- case 0: /* dark */
- pm = xpmDarkSquare;
- break;
- case 2: /* neutral */
- default:
- pm = xpmJailSquare;
- break;
- }
- XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
- squareSize, squareSize, x, y);
- } else {
- GC gc;
- switch (color) {
- case 1: /* light */
- gc = lightSquareGC;
- break;
- case 0: /* dark */
- gc = darkSquareGC;
- break;
- case 2: /* neutral */
- default:
- gc = jailSquareGC;
- break;
- }
- XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize);
- }
-}
-
-/*
- I split out the routines to draw a piece so that I could
- make a generic flash routine.
-*/
-static void monoDrawPiece_1bit(piece, square_color, x, y, dest)
- ChessSquare piece;
- int square_color, x, y;
- Drawable dest;
-{
- /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
- switch (square_color) {
- case 1: /* light */
- case 2: /* neutral */
- default:
- XCopyArea(xDisplay, (int) piece < (int) BlackPawn
- ? *pieceToOutline(piece)
- : *pieceToSolid(piece),
- dest, bwPieceGC, 0, 0,
- squareSize, squareSize, x, y);
- break;
- case 0: /* dark */
- XCopyArea(xDisplay, (int) piece < (int) BlackPawn
- ? *pieceToSolid(piece)
- : *pieceToOutline(piece),
- dest, wbPieceGC, 0, 0,
- squareSize, squareSize, x, y);
- break;
- }
-}
-
-static void monoDrawPiece(piece, square_color, x, y, dest)
- ChessSquare piece;
- int square_color, x, y;
- Drawable dest;
-{
- switch (square_color) {
- case 1: /* light */
- case 2: /* neutral */
- default:
- XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
- ? *pieceToOutline(piece)
- : *pieceToSolid(piece),
- dest, bwPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- break;
- case 0: /* dark */
- XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
- ? *pieceToSolid(piece)
- : *pieceToOutline(piece),
- dest, wbPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- break;
- }
-}
-
-static void colorDrawPiece(piece, square_color, x, y, dest)
- ChessSquare piece;
- int square_color, x, y;
- Drawable dest;
-{
- switch (square_color) {
- case 1: /* light */
- XCopyPlane(xDisplay, *pieceToSolid(piece),
- dest, (int) piece < (int) BlackPawn
- ? wlPieceGC : blPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- break;
- case 0: /* dark */
- XCopyPlane(xDisplay, *pieceToSolid(piece),
- dest, (int) piece < (int) BlackPawn
- ? wdPieceGC : bdPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- break;
- case 2: /* neutral */
- default:
- XCopyPlane(xDisplay, *pieceToSolid(piece),
- dest, (int) piece < (int) BlackPawn
- ? wjPieceGC : bjPieceGC, 0, 0,
- squareSize, squareSize, x, y, 1);
- break;
- }
-}
-
-static void colorDrawPieceImage(piece, square_color, x, y, dest)
- ChessSquare piece;
- int square_color, x, y;
- Drawable dest;
-{
- int kind;
-
- switch (square_color) {
- case 1: /* light */
- case 2: /* neutral */
- default:
- if ((int)piece < (int) BlackPawn) {
- kind = 0;
- } else {
- kind = 2;
- piece -= BlackPawn;
- }
- break;
- case 0: /* dark */
- if ((int)piece < (int) BlackPawn) {
- kind = 1;
- } else {
- kind = 3;
- piece -= BlackPawn;
- }
- break;
- }
- XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
- dest, wlPieceGC, 0, 0,
- squareSize, squareSize, x, y);
-}
-
-typedef void (*DrawFunc)();
-
-DrawFunc ChooseDrawFunc()
-{
- if (appData.monoMode) {
- if (DefaultDepth(xDisplay, xScreen) == 1) {
- return monoDrawPiece_1bit;
- } else {
- return monoDrawPiece;
- }
- } else {
- if (useImages)
- return colorDrawPieceImage;
- else
- return colorDrawPiece;
- }
-}
-
-void DrawSquare(row, column, piece, do_flash)
- int row, column, do_flash;
- ChessSquare piece;
-{
- int square_color, x, y, direction, font_ascent, font_descent;
- int i;
- char string[2];
- XCharStruct overall;
- DrawFunc drawfunc;
- int flash_delay;
-
- /* Calculate delay in milliseconds (2-delays per complete flash) */
- flash_delay = 500 / appData.flashRate;
-
- if (flipView) {
- x = lineGap + ((BOARD_SIZE-1)-column) *
- (squareSize + lineGap);
- y = lineGap + row * (squareSize + lineGap);
- } else {
- x = lineGap + column * (squareSize + lineGap);
- y = lineGap + ((BOARD_SIZE-1)-row) *
- (squareSize + lineGap);
- }
-
- square_color = ((column + row) % 2) == 1;
-
- if (piece == EmptySquare || appData.blindfold) {
- BlankSquare(x, y, square_color, piece, xBoardWindow);
- } else {
- drawfunc = ChooseDrawFunc();
- if (do_flash && appData.flashCount > 0) {
- for (i=0; i<appData.flashCount; ++i) {
-
- drawfunc(piece, square_color, x, y, xBoardWindow);
- XSync(xDisplay, False);
- do_flash_delay(flash_delay);
-
- BlankSquare(x, y, square_color, piece, xBoardWindow);
- XSync(xDisplay, False);
- do_flash_delay(flash_delay);
- }
- }
- drawfunc(piece, square_color, x, y, xBoardWindow);
- }
-
- string[1] = NULLCHAR;
- if (appData.showCoords && row == (flipView ? 7 : 0)) {
- string[0] = 'a' + column;
- XTextExtents(coordFontStruct, string, 1, &direction,
- &font_ascent, &font_descent, &overall);
- if (appData.monoMode) {
- XDrawImageString(xDisplay, xBoardWindow, coordGC,
- x + squareSize - overall.width - 2,
- y + squareSize - font_descent - 1, string, 1);
- } else {
- XDrawString(xDisplay, xBoardWindow, coordGC,
- x + squareSize - overall.width - 2,
- y + squareSize - font_descent - 1, string, 1);
- }
- }
- if (appData.showCoords && column == (flipView ? 7 : 0)) {
- string[0] = '1' + row;
- XTextExtents(coordFontStruct, string, 1, &direction,
- &font_ascent, &font_descent, &overall);
- if (appData.monoMode) {
- XDrawImageString(xDisplay, xBoardWindow, coordGC,
- x + 2, y + font_ascent + 1, string, 1);
- } else {
- XDrawString(xDisplay, xBoardWindow, coordGC,
- x + 2, y + font_ascent + 1, string, 1);
- }
- }
-}
-
-
-/* Why is this needed on some versions of X? */
-void EventProc(widget, unused, event)
- Widget widget;
- caddr_t unused;
- XEvent *event;
-{
- if (!XtIsRealized(widget))
- return;
-
- switch (event->type) {
- case Expose:
- if (event->xexpose.count > 0) return; /* no clipping is done */
- XDrawPosition(widget, True, NULL);
- break;
- default:
- return;
- }
-}
-/* end why */
-
-void DrawPosition(fullRedraw, board)
- /*Boolean*/int fullRedraw;
- Board board;
-{
- XDrawPosition(boardWidget, fullRedraw, board);
-}
-
-/* Returns 1 if there are "too many" differences between b1 and b2
- (i.e. more than 1 move was made) */
-static int too_many_diffs(b1, b2)
- Board b1, b2;
-{
- int i, j;
- int c = 0;
-
- for (i=0; i<BOARD_SIZE; ++i) {
- for (j=0; j<BOARD_SIZE; ++j) {
- if (b1[i][j] != b2[i][j]) {
- if (++c > 4) /* Castling causes 4 diffs */
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-/* Matrix describing castling maneuvers */
-/* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */
-static int castling_matrix[4][5] = {
- { 0, 0, 4, 3, 2 }, /* 0-0-0, white */
- { 0, 7, 4, 5, 6 }, /* 0-0, white */
- { 7, 0, 4, 3, 2 }, /* 0-0-0, black */
- { 7, 7, 4, 5, 6 } /* 0-0, black */
-};
-
-/* Checks whether castling occurred. If it did, *rrow and *rcol
- are set to the destination (row,col) of the rook that moved.
-
- Returns 1 if castling occurred, 0 if not.
-
- Note: Only handles a max of 1 castling move, so be sure
- to call too_many_diffs() first.
- */
-static int check_castle_draw(newb, oldb, rrow, rcol)
- Board newb, oldb;
- int *rrow, *rcol;
-{
- int i, *r, j;
- int match;
-
- /* For each type of castling... */
- for (i=0; i<4; ++i) {
- r = castling_matrix[i];
-
- /* Check the 4 squares involved in the castling move */
- match = 0;
- for (j=1; j<=4; ++j) {
- if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) {
- match = 1;
- break;
- }
- }
-
- if (!match) {
- /* All 4 changed, so it must be a castling move */
- *rrow = r[0];
- *rcol = r[3];
- return 1;
- }
- }
- return 0;
-}
-
-static int damage[BOARD_SIZE][BOARD_SIZE];
-
-/*
- * event handler for redrawing the board
- */
-void XDrawPosition(w, repaint, board)
- Widget w;
- /*Boolean*/int repaint;
- Board board;
-{
- int i, j, do_flash;
- static int lastFlipView = 0;
- static int lastBoardValid = 0;
- static Board lastBoard;
- Arg args[16];
- int rrow, rcol;
-
- if (board == NULL) {
- if (!lastBoardValid) return;
- board = lastBoard;
- }
- if (!lastBoardValid || lastFlipView != flipView) {
- XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
- args, 1);
- }
-
- /*
- * It would be simpler to clear the window with XClearWindow()
- * but this causes a very distracting flicker.
- */
-
- if (!repaint && lastBoardValid && lastFlipView == flipView) {
-
- /* If too much changes (begin observing new game, etc.), don't
- do flashing */
- do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
-
- /* Special check for castling so we don't flash both the king
- and the rook (just flash the king). */
- if (do_flash) {
- if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
- /* Draw rook with NO flashing. King will be drawn flashing later */
- DrawSquare(rrow, rcol, board[rrow][rcol], 0);
- lastBoard[rrow][rcol] = board[rrow][rcol];
- }
- }
-
- /* First pass -- Draw (newly) empty squares and repair damage.
- This prevents you from having a piece show up twice while it
- is flashing on its new square */
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++)
- if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
- || damage[i][j]) {
- DrawSquare(i, j, board[i][j], 0);
- damage[i][j] = False;
- }
-
- /* Second pass -- Draw piece(s) in new position and flash them */
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++)
- if (board[i][j] != lastBoard[i][j]) {
- DrawSquare(i, j, board[i][j], do_flash);
- }
- } else {
- if (lineGap > 0)
- XDrawSegments(xDisplay, xBoardWindow, lineGC,
- gridSegments, (BOARD_SIZE + 1) * 2);
-
- for (i = 0; i < BOARD_SIZE; i++)
- for (j = 0; j < BOARD_SIZE; j++) {
- DrawSquare(i, j, board[i][j], 0);
- damage[i][j] = False;
- }
- }
-
- CopyBoard(lastBoard, board);
- lastBoardValid = 1;
- lastFlipView = flipView;
-
- /* Draw highlights */
- if (pm1X >= 0 && pm1Y >= 0) {
- drawHighlight(pm1X, pm1Y, prelineGC);
- }
- if (pm2X >= 0 && pm2Y >= 0) {
- drawHighlight(pm2X, pm2Y, prelineGC);
- }
- if (hi1X >= 0 && hi1Y >= 0) {
- drawHighlight(hi1X, hi1Y, highlineGC);
- }
- if (hi2X >= 0 && hi2Y >= 0) {
- drawHighlight(hi2X, hi2Y, highlineGC);
- }
-
- /* If piece being dragged around board, must redraw that too */
- DrawDragPiece();
-
- XSync(xDisplay, False);
-}
-
-
-/*
- * event handler for redrawing the board
- */
-void DrawPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- XDrawPosition(w, True, NULL);
-}
-
-
-/*
- * event handler for parsing user moves
- */
-void HandleUserMove(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- int x, y;
- Boolean saveAnimate;
- static int second = 0;
-
- if (w != boardWidget || errorExitStatus != -1) return;
-
- if (event->type == ButtonPress) ErrorPopDown();
-
- if (promotionUp) {
- if (event->type == ButtonPress) {
- XtPopdown(promotionShell);
- XtDestroyWidget(promotionShell);
- promotionUp = False;
- ClearHighlights();
- fromX = fromY = -1;
- } else {
- return;
- }
- }
-
- x = EventToSquare(event->xbutton.x, BOARD_SIZE);
- y = EventToSquare(event->xbutton.y, BOARD_SIZE);
- if (!flipView && y >= 0) {
- y = BOARD_SIZE - 1 - y;
- }
- if (flipView && x >= 0) {
- x = BOARD_SIZE - 1 - x;
- }
-
- if (fromX == -1) {
- if (event->type == ButtonPress) {
- /* First square */
- if (OKToStartUserMove(x, y)) {
- fromX = x;
- fromY = y;
- second = 0;
- DragPieceBegin(event->xbutton.x, event->xbutton.y);
- if (appData.highlightDragging) {
- SetHighlights(x, y, -1, -1);
- }
- }
- }
- return;
- }
-
- /* fromX != -1 */
- if (event->type == ButtonPress && gameMode != EditPosition &&
- x >= 0 && y >= 0) {
- ChessSquare fromP;
- ChessSquare toP;
- /* Check if clicking again on the same color piece */
- fromP = boards[currentMove][fromY][fromX];
- toP = boards[currentMove][y][x];
- if ((WhitePawn <= fromP && fromP <= WhiteKing &&
- WhitePawn <= toP && toP <= WhiteKing) ||
- (BlackPawn <= fromP && fromP <= BlackKing &&
- BlackPawn <= toP && toP <= BlackKing)) {
- /* Clicked again on same color piece -- changed his mind */
- second = (x == fromX && y == fromY);
- if (appData.highlightDragging) {
- SetHighlights(x, y, -1, -1);
- } else {
- ClearHighlights();
- }
- if (OKToStartUserMove(x, y)) {
- fromX = x;
- fromY = y;
- DragPieceBegin(event->xbutton.x, event->xbutton.y);
- }
- return;
- }
- }
-
- if (event->type == ButtonRelease && x == fromX && y == fromY) {
- DragPieceEnd(event->xbutton.x, event->xbutton.y);
- if (appData.animateDragging) {
- /* Undo animation damage if any */
- DrawPosition(FALSE, NULL);
- }
- if (second) {
- /* Second up/down in same square; just abort move */
- second = 0;
- fromX = fromY = -1;
- ClearHighlights();
- gotPremove = 0;
- ClearPremoveHighlights();
- } else {
- /* First upclick in same square; start click-click mode */
- SetHighlights(x, y, -1, -1);
- }
- return;
- }
-
- /* Completed move */
- toX = x;
- toY = y;
- saveAnimate = appData.animate;
- if (event->type == ButtonPress) {
- /* Finish clickclick move */
- if (appData.animate || appData.highlightLastMove) {
- SetHighlights(fromX, fromY, toX, toY);
- } else {
- ClearHighlights();
- }
- } else {
- /* Finish drag move */
- if (appData.highlightLastMove) {
- SetHighlights(fromX, fromY, toX, toY);
- } else {
- ClearHighlights();
- }
- DragPieceEnd(event->xbutton.x, event->xbutton.y);
- /* Don't animate move and drag both */
- appData.animate = FALSE;
- }
- if (IsPromotion(fromX, fromY, toX, toY)) {
- if (appData.alwaysPromoteToQueen) {
- UserMoveEvent(fromX, fromY, toX, toY, 'q');
- if (!appData.highlightLastMove || gotPremove) ClearHighlights();
- if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
- fromX = fromY = -1;
- } else {
- SetHighlights(fromX, fromY, toX, toY);
- PromotionPopUp();
- }
- } else {
- UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
- if (!appData.highlightLastMove || gotPremove) ClearHighlights();
- if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
- fromX = fromY = -1;
- }
- appData.animate = saveAnimate;
- if (appData.animate || appData.animateDragging) {
- /* Undo animation damage if needed */
- DrawPosition(FALSE, NULL);
- }
-}
-
-void AnimateUserMove (Widget w, XEvent * event,
- String * params, Cardinal * nParams)
-{
- DragPieceMove(event->xmotion.x, event->xmotion.y);
-}
-
-Widget CommentCreate(name, text, mutable, callback, lines)
- char *name, *text;
- int /*Boolean*/ mutable;
- XtCallbackProc callback;
- int lines;
-{
- Arg args[16];
- Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
- Dimension bw_width;
- int j;
-
- j = 0;
- XtSetArg(args[j], XtNwidth, &bw_width); j++;
- XtGetValues(boardWidget, args, j);
-
- j = 0;
- XtSetArg(args[j], XtNresizable, True); j++;
-#if TOPLEVEL
- shell =
- XtCreatePopupShell(name, topLevelShellWidgetClass,
- shellWidget, args, j);
-#else
- shell =
- XtCreatePopupShell(name, transientShellWidgetClass,
- shellWidget, args, j);
-#endif
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, shell,
- layoutArgs, XtNumber(layoutArgs));
- form =
- XtCreateManagedWidget("form", formWidgetClass, layout,
- formArgs, XtNumber(formArgs));
-
- j = 0;
- if (mutable) {
- XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
- XtSetArg(args[j], XtNuseStringInPlace, False); j++;
- }
- XtSetArg(args[j], XtNstring, text); j++;
- XtSetArg(args[j], XtNtop, XtChainTop); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainRight); j++;
- XtSetArg(args[j], XtNresizable, True); j++;
- XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/
-#if 0
- XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
-#else
- /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
- XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
-#endif
- XtSetArg(args[j], XtNautoFill, True); j++;
- XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
- edit =
- XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
-
- if (mutable) {
- j = 0;
- XtSetArg(args[j], XtNfromVert, edit); j++;
- XtSetArg(args[j], XtNtop, XtChainBottom); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainLeft); j++;
- b_ok =
- XtCreateManagedWidget("ok", commandWidgetClass, form, args, j);
- XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
-
- j = 0;
- XtSetArg(args[j], XtNfromVert, edit); j++;
- XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
- XtSetArg(args[j], XtNtop, XtChainBottom); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainLeft); j++;
- b_cancel =
- XtCreateManagedWidget("cancel", commandWidgetClass, form, args, j);
- XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
-
- j = 0;
- XtSetArg(args[j], XtNfromVert, edit); j++;
- XtSetArg(args[j], XtNfromHoriz, b_cancel); j++;
- XtSetArg(args[j], XtNtop, XtChainBottom); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainLeft); j++;
- b_clear =
- XtCreateManagedWidget("clear", commandWidgetClass, form, args, j);
- XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
- } else {
- j = 0;
- XtSetArg(args[j], XtNfromVert, edit); j++;
- XtSetArg(args[j], XtNtop, XtChainBottom); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainLeft); j++;
- b_close =
- XtCreateManagedWidget("close", commandWidgetClass, form, args, j);
- XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
-
- j = 0;
- XtSetArg(args[j], XtNfromVert, edit); j++;
- XtSetArg(args[j], XtNfromHoriz, b_close); j++;
- XtSetArg(args[j], XtNtop, XtChainBottom); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainLeft); j++;
- b_edit =
- XtCreateManagedWidget("edit", commandWidgetClass, form, args, j);
- XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
- }
-
- XtRealizeWidget(shell);
-
- if (commentX == -1) {
- int xx, yy;
- Window junk;
- Dimension pw_height;
- Dimension ew_height;
-
- j = 0;
- XtSetArg(args[j], XtNheight, &ew_height); j++;
- XtGetValues(edit, args, j);
-
- j = 0;
- XtSetArg(args[j], XtNheight, &pw_height); j++;
- XtGetValues(shell, args, j);
- commentH = pw_height + (lines - 1) * ew_height;
- commentW = bw_width - 16;
-
- XSync(xDisplay, False);
-#ifdef NOTDEF
- /* This code seems to tickle an X bug if it is executed too soon
- after xboard starts up. The coordinates get transformed as if
- the main window was positioned at (0, 0).
- */
- XtTranslateCoords(shellWidget,
- (bw_width - commentW) / 2, 0 - commentH / 2,
- &commentX, &commentY);
-#else /*!NOTDEF*/
- XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
- RootWindowOfScreen(XtScreen(shellWidget)),
- (bw_width - commentW) / 2, 0 - commentH / 2,
- &xx, &yy, &junk);
- commentX = xx;
- commentY = yy;
-#endif /*!NOTDEF*/
- if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/
- }
- j = 0;
- XtSetArg(args[j], XtNheight, commentH); j++;
- XtSetArg(args[j], XtNwidth, commentW); j++;
- XtSetArg(args[j], XtNx, commentX); j++;
- XtSetArg(args[j], XtNy, commentY); j++;
- XtSetValues(shell, args, j);
- XtSetKeyboardFocus(shell, edit);
-
- return shell;
-}
-
-/* Used for analysis window and ICS input window */
-Widget MiscCreate(name, text, mutable, callback, lines)
- char *name, *text;
- int /*Boolean*/ mutable;
- XtCallbackProc callback;
- int lines;
-{
- Arg args[16];
- Widget shell, layout, form, edit;
- Position x, y;
- Dimension bw_width, pw_height, ew_height, w, h;
- int j;
- int xx, yy;
- Window junk;
-
- j = 0;
- XtSetArg(args[j], XtNresizable, True); j++;
-#if TOPLEVEL
- shell =
- XtCreatePopupShell(name, topLevelShellWidgetClass,
- shellWidget, args, j);
-#else
- shell =
- XtCreatePopupShell(name, transientShellWidgetClass,
- shellWidget, args, j);
-#endif
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, shell,
- layoutArgs, XtNumber(layoutArgs));
- form =
- XtCreateManagedWidget("form", formWidgetClass, layout,
- formArgs, XtNumber(formArgs));
-
- j = 0;
- if (mutable) {
- XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
- XtSetArg(args[j], XtNuseStringInPlace, False); j++;
- }
- XtSetArg(args[j], XtNstring, text); j++;
- XtSetArg(args[j], XtNtop, XtChainTop); j++;
- XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
- XtSetArg(args[j], XtNleft, XtChainLeft); j++;
- XtSetArg(args[j], XtNright, XtChainRight); j++;
- XtSetArg(args[j], XtNresizable, True); j++;
-#if 0
- XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
-#else
- /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
- XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
-#endif
- XtSetArg(args[j], XtNautoFill, True); j++;
- XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
- edit =
- XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
-
- XtRealizeWidget(shell);
-
- j = 0;
- XtSetArg(args[j], XtNwidth, &bw_width); j++;
- XtGetValues(boardWidget, args, j);
-
- j = 0;
- XtSetArg(args[j], XtNheight, &ew_height); j++;
- XtGetValues(edit, args, j);
-
- j = 0;
- XtSetArg(args[j], XtNheight, &pw_height); j++;
- XtGetValues(shell, args, j);
- h = pw_height + (lines - 1) * ew_height;
- w = bw_width - 16;
-
- XSync(xDisplay, False);
-#ifdef NOTDEF
- /* This code seems to tickle an X bug if it is executed too soon
- after xboard starts up. The coordinates get transformed as if
- the main window was positioned at (0, 0).
- */
- XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);
-#else /*!NOTDEF*/
- XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
- RootWindowOfScreen(XtScreen(shellWidget)),
- (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
-#endif /*!NOTDEF*/
- x = xx;
- y = yy;
- if (y < 0) y = 0; /*avoid positioning top offscreen*/
-
- j = 0;
- XtSetArg(args[j], XtNheight, h); j++;
- XtSetArg(args[j], XtNwidth, w); j++;
- XtSetArg(args[j], XtNx, x); j++;
- XtSetArg(args[j], XtNy, y); j++;
- XtSetValues(shell, args, j);
-
- return shell;
-}
-
-
-static int savedIndex; /* gross that this is global */
-
-void EditCommentPopUp(index, title, text)
- int index;
- char *title, *text;
-{
- Widget edit;
- Arg args[16];
- int j;
-
- savedIndex = index;
- if (text == NULL) text = "";
-
- if (editShell == NULL) {
- editShell =
- CommentCreate(title, text, True, EditCommentCallback, 4);
- XtRealizeWidget(editShell);
- CatchDeleteWindow(editShell, "EditCommentPopDown");
- } else {
- edit = XtNameToWidget(editShell, "*form.text");
- j = 0;
- XtSetArg(args[j], XtNstring, text); j++;
- XtSetValues(edit, args, j);
- j = 0;
- XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
- XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
- XtSetValues(editShell, args, j);
- }
-
- XtPopup(editShell, XtGrabNone);
-
- editUp = True;
- j = 0;
- XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
- XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
- args, j);
-}
-
-void EditCommentCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
-{
- String name, val;
- Arg args[16];
- int j;
- Widget edit;
-
- j = 0;
- XtSetArg(args[j], XtNlabel, &name); j++;
- XtGetValues(w, args, j);
-
- if (strcmp(name, "ok") == 0) {
- edit = XtNameToWidget(editShell, "*form.text");
- j = 0;
- XtSetArg(args[j], XtNstring, &val); j++;
- XtGetValues(edit, args, j);
- ReplaceComment(savedIndex, val);
- EditCommentPopDown();
- } else if (strcmp(name, "cancel") == 0) {
- EditCommentPopDown();
- } else if (strcmp(name, "clear") == 0) {
- edit = XtNameToWidget(editShell, "*form.text");
- XtCallActionProc(edit, "select-all", NULL, NULL, 0);
- XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
- }
-}
-
-void EditCommentPopDown()
-{
- Arg args[16];
- int j;
-
- if (!editUp) return;
- j = 0;
- XtSetArg(args[j], XtNx, &commentX); j++;
- XtSetArg(args[j], XtNy, &commentY); j++;
- XtSetArg(args[j], XtNheight, &commentH); j++;
- XtSetArg(args[j], XtNwidth, &commentW); j++;
- XtGetValues(editShell, args, j);
- XtPopdown(editShell);
- editUp = False;
- j = 0;
- XtSetArg(args[j], XtNleftBitmap, None); j++;
- XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
- args, j);
-}
-
-void ICSInputBoxPopUp()
-{
- Widget edit;
- Arg args[16];
- int j;
- char *title = "ICS Input";
- XtTranslations tr;
-
- if (ICSInputShell == NULL) {
- ICSInputShell = MiscCreate(title, "", True, NULL, 1);
- tr = XtParseTranslationTable(ICSInputTranslations);
- edit = XtNameToWidget(ICSInputShell, "*form.text");
- XtOverrideTranslations(edit, tr);
- XtRealizeWidget(ICSInputShell);
- CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
-
- } else {
- edit = XtNameToWidget(ICSInputShell, "*form.text");
- j = 0;
- XtSetArg(args[j], XtNstring, ""); j++;
- XtSetValues(edit, args, j);
- j = 0;
- XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
- XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
- XtSetValues(ICSInputShell, args, j);
- }
-
- XtPopup(ICSInputShell, XtGrabNone);
- XtSetKeyboardFocus(ICSInputShell, edit);
-
- ICSInputBoxUp = True;
- j = 0;
- XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
- XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
- args, j);
-}
-
-void ICSInputSendText()
-{
- Widget edit;
- int j;
- Arg args[16];
- String val;
-
- edit = XtNameToWidget(ICSInputShell, "*form.text");
- j = 0;
- XtSetArg(args[j], XtNstring, &val); j++;
- XtGetValues(edit, args, j);
- SendMultiLineToICS(val);
- XtCallActionProc(edit, "select-all", NULL, NULL, 0);
- XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
-}
-
-void ICSInputBoxPopDown()
-{
- Arg args[16];
- int j;
-
- if (!ICSInputBoxUp) return;
- j = 0;
- XtPopdown(ICSInputShell);
- ICSInputBoxUp = False;
- j = 0;
- XtSetArg(args[j], XtNleftBitmap, None); j++;
- XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
- args, j);
-}
-
-void CommentPopUp(title, text)
- char *title, *text;
-{
- Arg args[16];
- int j;
- Widget edit;
-
- if (commentShell == NULL) {
- commentShell =
- CommentCreate(title, text, False, CommentCallback, 4);
- XtRealizeWidget(commentShell);
- CatchDeleteWindow(commentShell, "CommentPopDown");
- } else {
- edit = XtNameToWidget(commentShell, "*form.text");
- j = 0;
- XtSetArg(args[j], XtNstring, text); j++;
- XtSetValues(edit, args, j);
- j = 0;
- XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
- XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
- XtSetValues(commentShell, args, j);
- }
-
- XtPopup(commentShell, XtGrabNone);
- XSync(xDisplay, False);
-
- commentUp = True;
-}
-
-void AnalysisPopUp(title, text)
- char *title, *text;
-{
- Arg args[16];
- int j;
- Widget edit;
-
- if (analysisShell == NULL) {
- analysisShell = MiscCreate(title, text, False, NULL, 4);
- XtRealizeWidget(analysisShell);
- CatchDeleteWindow(analysisShell, "AnalysisPopDown");
-
- } else {
- edit = XtNameToWidget(analysisShell, "*form.text");
- j = 0;
- XtSetArg(args[j], XtNstring, text); j++;
- XtSetValues(edit, args, j);
- j = 0;
- XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
- XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
- XtSetValues(analysisShell, args, j);
- }
-
- if (!analysisUp) {
- XtPopup(analysisShell, XtGrabNone);
- }
- XSync(xDisplay, False);
-
- analysisUp = True;
-}
-
-void CommentCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
-{
- String name;
- Arg args[16];
- int j;
-
- j = 0;
- XtSetArg(args[j], XtNlabel, &name); j++;
- XtGetValues(w, args, j);
-
- if (strcmp(name, "close") == 0) {
- CommentPopDown();
- } else if (strcmp(name, "edit") == 0) {
- CommentPopDown();
- EditCommentEvent();
- }
-}
-
-
-void CommentPopDown()
-{
- Arg args[16];
- int j;
-
- if (!commentUp) return;
- j = 0;
- XtSetArg(args[j], XtNx, &commentX); j++;
- XtSetArg(args[j], XtNy, &commentY); j++;
- XtSetArg(args[j], XtNwidth, &commentW); j++;
- XtSetArg(args[j], XtNheight, &commentH); j++;
- XtGetValues(commentShell, args, j);
- XtPopdown(commentShell);
- XSync(xDisplay, False);
- commentUp = False;
-}
-
-void AnalysisPopDown()
-{
- if (!analysisUp) return;
- XtPopdown(analysisShell);
- XSync(xDisplay, False);
- analysisUp = False;
-}
-
-
-void FileNamePopUp(label, def, proc, openMode)
- char *label;
- char *def;
- FileProc proc;
- char *openMode;
-{
- Arg args[16];
- Widget popup, layout, dialog, edit;
- Window root, child;
- int x, y, i;
- int win_x, win_y;
- unsigned int mask;
-
- fileProc = proc; /* I can't see a way not */
- fileOpenMode = openMode; /* to use globals here */
-
- i = 0;
- XtSetArg(args[i], XtNresizable, True); i++;
- XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
- fileNameShell = popup =
- XtCreatePopupShell("File name prompt", transientShellWidgetClass,
- shellWidget, args, i);
-
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, popup,
- layoutArgs, XtNumber(layoutArgs));
-
- i = 0;
- XtSetArg(args[i], XtNlabel, label); i++;
- XtSetArg(args[i], XtNvalue, def); i++;
- XtSetArg(args[i], XtNborderWidth, 0); i++;
- dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
- layout, args, i);
-
- XawDialogAddButton(dialog, "ok", FileNameCallback, (XtPointer) dialog);
- XawDialogAddButton(dialog, "cancel", FileNameCallback,
- (XtPointer) dialog);
-
- XtRealizeWidget(popup);
- CatchDeleteWindow(popup, "FileNamePopDown");
-
- XQueryPointer(xDisplay, xBoardWindow, &root, &child,
- &x, &y, &win_x, &win_y, &mask);
-
- XtSetArg(args[0], XtNx, x - 10);
- XtSetArg(args[1], XtNy, y - 30);
- XtSetValues(popup, args, 2);
-
- XtPopup(popup, XtGrabExclusive);
- filenameUp = True;
-
- edit = XtNameToWidget(dialog, "*value");
- XtSetKeyboardFocus(popup, edit);
-}
-
-void FileNamePopDown()
-{
- if (!filenameUp) return;
- XtPopdown(fileNameShell);
- XtDestroyWidget(fileNameShell);
- filenameUp = False;
- ModeHighlight();
-}
-
-void FileNameCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
-{
- String name;
- Arg args[16];
-
- XtSetArg(args[0], XtNlabel, &name);
- XtGetValues(w, args, 1);
-
- if (strcmp(name, "cancel") == 0) {
- FileNamePopDown();
- return;
- }
-
- FileNameAction(w, NULL, NULL, NULL);
-}
-
-void FileNameAction(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- char buf[MSG_SIZ];
- String name;
- FILE *f;
- char *p, *fullname;
- int index;
-
- name = XawDialogGetValueString(w = XtParent(w));
-
- if ((name != NULL) && (*name != NULLCHAR)) {
- strcpy(buf, name);
- XtPopdown(w = XtParent(XtParent(w)));
- XtDestroyWidget(w);
- filenameUp = False;
-
- p = strrchr(buf, ' ');
- if (p == NULL) {
- index = 0;
- } else {
- *p++ = NULLCHAR;
- index = atoi(p);
- }
- fullname = ExpandPathName(buf);
- if (!fullname) {
- ErrorPopUp("Error", "Can't open file", FALSE);
- }
- else {
- f = fopen(fullname, fileOpenMode);
- if (f == NULL) {
- DisplayError("Failed to open file", errno);
- } else {
- (void) (*fileProc)(f, index, buf);
- }
- }
- ModeHighlight();
- return;
- }
-
- XtPopdown(w = XtParent(XtParent(w)));
- XtDestroyWidget(w);
- filenameUp = False;
- ModeHighlight();
-}
-
-void PromotionPopUp()
-{
- Arg args[16];
- Widget dialog, layout;
- Position x, y;
- Dimension bw_width, pw_width;
- int j;
-
- j = 0;
- XtSetArg(args[j], XtNwidth, &bw_width); j++;
- XtGetValues(boardWidget, args, j);
-
- j = 0;
- XtSetArg(args[j], XtNresizable, True); j++;
- promotionShell =
- XtCreatePopupShell("Promotion", transientShellWidgetClass,
- shellWidget, args, j);
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
- layoutArgs, XtNumber(layoutArgs));
-
- j = 0;
- XtSetArg(args[j], XtNlabel, "Promote pawn to what?"); j++;
- XtSetArg(args[j], XtNborderWidth, 0); j++;
- dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
- layout, args, j);
-
- XawDialogAddButton(dialog, "Queen", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "Rook", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "Bishop", PromotionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "Knight", PromotionCallback,
- (XtPointer) dialog);
- if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
- gameInfo.variant == VariantGiveaway) {
- XawDialogAddButton(dialog, "King", PromotionCallback,
- (XtPointer) dialog);
- }
- XawDialogAddButton(dialog, "cancel", PromotionCallback,
- (XtPointer) dialog);
-
- XtRealizeWidget(promotionShell);
- CatchDeleteWindow(promotionShell, "PromotionPopDown");
-
- j = 0;
- XtSetArg(args[j], XtNwidth, &pw_width); j++;
- XtGetValues(promotionShell, args, j);
-
- XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
- lineGap + squareSize/3 +
- ((toY == 7) ^ (flipView) ?
- 0 : 6*(squareSize + lineGap)), &x, &y);
-
- j = 0;
- XtSetArg(args[j], XtNx, x); j++;
- XtSetArg(args[j], XtNy, y); j++;
- XtSetValues(promotionShell, args, j);
-
- XtPopup(promotionShell, XtGrabNone);
-
- promotionUp = True;
-}
-
-void PromotionPopDown()
-{
- if (!promotionUp) return;
- XtPopdown(promotionShell);
- XtDestroyWidget(promotionShell);
- promotionUp = False;
-}
-
-void PromotionCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
-{
- String name;
- Arg args[16];
- int promoChar;
-
- XtSetArg(args[0], XtNlabel, &name);
- XtGetValues(w, args, 1);
-
- PromotionPopDown();
-
- if (fromX == -1) return;
-
- if (strcmp(name, "cancel") == 0) {
- fromX = fromY = -1;
- ClearHighlights();
- return;
- } else if (strcmp(name, "Knight") == 0) {
- promoChar = 'n';
- } else {
- promoChar = ToLower(name[0]);
- }
-
- UserMoveEvent(fromX, fromY, toX, toY, promoChar);
-
- if (!appData.highlightLastMove || gotPremove) ClearHighlights();
- if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
- fromX = fromY = -1;
-}
-
-
-void ErrorCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
-{
- errorUp = False;
- XtPopdown(w = XtParent(XtParent(XtParent(w))));
- XtDestroyWidget(w);
- if (errorExitStatus != -1) ExitEvent(errorExitStatus);
-}
-
-
-void ErrorPopDown()
-{
- if (!errorUp) return;
- errorUp = False;
- XtPopdown(errorShell);
- XtDestroyWidget(errorShell);
- if (errorExitStatus != -1) ExitEvent(errorExitStatus);
-}
-
-void ErrorPopUp(title, label, modal)
- char *title, *label;
- int modal;
-{
- Arg args[16];
- Widget dialog, layout;
- Position x, y;
- int xx, yy;
- Window junk;
- Dimension bw_width, pw_width;
- Dimension pw_height;
- int i;
-
- i = 0;
- XtSetArg(args[i], XtNresizable, True); i++;
- XtSetArg(args[i], XtNtitle, title); i++;
- errorShell =
- XtCreatePopupShell("errorpopup", transientShellWidgetClass,
- shellWidget, args, i);
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,
- layoutArgs, XtNumber(layoutArgs));
-
- i = 0;
- XtSetArg(args[i], XtNlabel, label); i++;
- XtSetArg(args[i], XtNborderWidth, 0); i++;
- dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
- layout, args, i);
-
- XawDialogAddButton(dialog, "ok", ErrorCallback, (XtPointer) dialog);
-
- XtRealizeWidget(errorShell);
- CatchDeleteWindow(errorShell, "ErrorPopDown");
-
- i = 0;
- XtSetArg(args[i], XtNwidth, &bw_width); i++;
- XtGetValues(boardWidget, args, i);
- i = 0;
- XtSetArg(args[i], XtNwidth, &pw_width); i++;
- XtSetArg(args[i], XtNheight, &pw_height); i++;
- XtGetValues(errorShell, args, i);
-
-#ifdef NOTDEF
- /* This code seems to tickle an X bug if it is executed too soon
- after xboard starts up. The coordinates get transformed as if
- the main window was positioned at (0, 0).
- */
- XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
- 0 - pw_height + squareSize / 3, &x, &y);
-#else
- XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
- RootWindowOfScreen(XtScreen(boardWidget)),
- (bw_width - pw_width) / 2,
- 0 - pw_height + squareSize / 3, &xx, &yy, &junk);
- x = xx;
- y = yy;
-#endif
- if (y < 0) y = 0; /*avoid positioning top offscreen*/
-
- i = 0;
- XtSetArg(args[i], XtNx, x); i++;
- XtSetArg(args[i], XtNy, y); i++;
- XtSetValues(errorShell, args, i);
-
- errorUp = True;
- XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);
-}
-
-/* Disable all user input other than deleting the window */
-static int frozen = 0;
-void FreezeUI()
-{
- if (frozen) return;
- /* Grab by a widget that doesn't accept input */
- XtAddGrab(messageWidget, TRUE, FALSE);
- frozen = 1;
-}
-
-/* Undo a FreezeUI */
-void ThawUI()
-{
- if (!frozen) return;
- XtRemoveGrab(messageWidget);
- frozen = 0;
-}
-
-char *ModeToWidgetName(mode)
- GameMode mode;
-{
- switch (mode) {
- case BeginningOfGame:
- if (appData.icsActive)
- return "menuMode.ICS Client";
- else if (appData.noChessProgram ||
- *appData.cmailGameName != NULLCHAR)
- return "menuMode.Edit Game";
- else
- return "menuMode.Machine Black";
- case MachinePlaysBlack:
- return "menuMode.Machine Black";
- case MachinePlaysWhite:
- return "menuMode.Machine White";
- case AnalyzeMode:
- return "menuMode.Analysis Mode";
- case AnalyzeFile:
- return "menuMode.Analyze File";
- case TwoMachinesPlay:
- return "menuMode.Two Machines";
- case EditGame:
- return "menuMode.Edit Game";
- case PlayFromGameFile:
- return "menuFile.Load Game";
- case EditPosition:
- return "menuMode.Edit Position";
- case Training:
- return "menuMode.Training";
- case IcsPlayingWhite:
- case IcsPlayingBlack:
- case IcsObserving:
- case IcsIdle:
- case IcsExamining:
- return "menuMode.ICS Client";
- default:
- case EndOfGame:
- return NULL;
- }
-}
-
-void ModeHighlight()
-{
- Arg args[16];
- static int oldPausing = FALSE;
- static GameMode oldmode = (GameMode) -1;
- char *wname;
-
- if (!boardWidget || !XtIsRealized(boardWidget)) return;
-
- if (pausing != oldPausing) {
- oldPausing = pausing;
- if (pausing) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),
- args, 1);
-
- if (appData.showButtonBar) {
-#if 0
- if (pausing) {
- XtSetArg(args[0], XtNbackground, buttonForegroundPixel);
- XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);
- } else {
- XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);
- XtSetArg(args[1], XtNforeground, buttonForegroundPixel);
- }
-#else
- /* Always toggle, don't set. Previous code messes up when
- invoked while the button is pressed, as releasing it
- toggles the state again. */
- {
- Pixel oldbg, oldfg;
- XtSetArg(args[0], XtNbackground, &oldbg);
- XtSetArg(args[1], XtNforeground, &oldfg);
- XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),
- args, 2);
- XtSetArg(args[0], XtNbackground, oldfg);
- XtSetArg(args[1], XtNforeground, oldbg);
- }
-#endif
- XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
- }
- }
-
- wname = ModeToWidgetName(oldmode);
- if (wname != NULL) {
- XtSetArg(args[0], XtNleftBitmap, None);
- XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
- }
- wname = ModeToWidgetName(gameMode);
- if (wname != NULL) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
- }
- oldmode = gameMode;
-
- /* Maybe all the enables should be handled here, not just this one */
- XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),
- gameMode == Training || gameMode == PlayFromGameFile);
-}
-
-
-/*
- * Button/menu procedures
- */
-void ResetProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ResetGameEvent();
- AnalysisPopDown();
-}
-
-int LoadGamePopUp(f, gameNumber, title)
- FILE *f;
- int gameNumber;
- char *title;
-{
- cmailMsgLoaded = FALSE;
- if (gameNumber == 0) {
- int error = GameListBuild(f);
- if (error) {
- DisplayError("Cannot build game list", error);
- } else if (!ListEmpty(&gameList) &&
- ((ListGame *) gameList.tailPred)->number > 1) {
- GameListPopUp(f, title);
- return TRUE;
- }
- GameListDestroy();
- gameNumber = 1;
- }
- return LoadGame(f, gameNumber, title, FALSE);
-}
-
-void LoadGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
- Reset(FALSE, TRUE);
- }
- FileNamePopUp("Load game file name?", "", LoadGamePopUp, "rb");
-}
-
-void LoadNextGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadGame(1);
-}
-
-void LoadPrevGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadGame(-1);
-}
-
-void ReloadGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadGame(0);
-}
-
-void LoadNextPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadPosition(1);
-}
-
-void LoadPrevPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadPosition(-1);
-}
-
-void ReloadPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadPosition(0);
-}
-
-void LoadPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
- Reset(FALSE, TRUE);
- }
- FileNamePopUp("Load position file name?", "", LoadPosition, "rb");
-}
-
-void SaveGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- FileNamePopUp("Save game file name?",
- DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
- SaveGame, "a");
-}
-
-void SavePositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- FileNamePopUp("Save position file name?",
- DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
- SavePosition, "a");
-}
-
-void ReloadCmailMsgProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ReloadCmailMsgEvent(FALSE);
-}
-
-void MailMoveProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- MailMoveEvent();
-}
-
-/* this variable is shared between CopyPositionProc and SendPositionSelection */
-static char *selected_fen_position=NULL;
-
-static Boolean
-SendPositionSelection(Widget w, Atom *selection, Atom *target,
- Atom *type_return, XtPointer *value_return,
- unsigned long *length_return, int *format_return)
-{
- char *selection_tmp;
-
- if (!selected_fen_position) return False; /* should never happen */
- if (*target == XA_STRING){
- /* note: since no XtSelectionDoneProc was registered, Xt will
- * automatically call XtFree on the value returned. So have to
- * make a copy of it allocated with XtMalloc */
- selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
- strcpy(selection_tmp, selected_fen_position);
-
- *value_return=selection_tmp;
- *length_return=strlen(selection_tmp);
- *type_return=XA_STRING;
- *format_return = 8; /* bits per byte */
- return True;
- } else {
- return False;
- }
-}
-
-/* note: when called from menu all parameters are NULL, so no clue what the
- * Widget which was clicked on was, or what the click event was
- */
-void CopyPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
- {
- int ret;
-
- if (selected_fen_position) free(selected_fen_position);
- selected_fen_position = (char *)PositionToFEN(currentMove);
- if (!selected_fen_position) return;
- ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
- CurrentTime,
- SendPositionSelection,
- NULL/* lose_ownership_proc */ ,
- NULL/* transfer_done_proc */);
- if (!ret) {
- free(selected_fen_position);
- selected_fen_position=NULL;
- }
- }
-
-/* function called when the data to Paste is ready */
-static void
-PastePositionCB(Widget w, XtPointer client_data, Atom *selection,
- Atom *type, XtPointer value, unsigned long *len, int *format)
-{
- char *fenstr=value;
- if (value==NULL || *len==0) return; /* nothing had been selected to copy */
- fenstr[*len]='\0'; /* normally this string is terminated, but be safe */
- EditPositionPasteFEN(fenstr);
- XtFree(value);
-}
-
-/* called when Paste Position button is pressed,
- * all parameters will be NULL */
-void PastePositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
- /* (XtSelectionCallbackProc) */ PastePositionCB,
- NULL, /* client_data passed to PastePositionCB */
-
- /* better to use the time field from the event that triggered the
- * call to this function, but that isn't trivial to get
- */
- CurrentTime
- );
- return;
-}
-
-static Boolean
-SendGameSelection(Widget w, Atom *selection, Atom *target,
- Atom *type_return, XtPointer *value_return,
- unsigned long *length_return, int *format_return)
-{
- char *selection_tmp;
-
- if (*target == XA_STRING){
- FILE* f = fopen(gameCopyFilename, "r");
- long len;
- size_t count;
- if (f == NULL) return False;
- fseek(f, 0, 2);
- len = ftell(f);
- rewind(f);
- selection_tmp = XtMalloc(len + 1);
- count = fread(selection_tmp, 1, len, f);
- if (len != count) {
- XtFree(selection_tmp);
- return False;
- }
- selection_tmp[len] = NULLCHAR;
- *value_return = selection_tmp;
- *length_return = len;
- *type_return = XA_STRING;
- *format_return = 8; /* bits per byte */
- return True;
- } else {
- return False;
- }
-}
-
-/* note: when called from menu all parameters are NULL, so no clue what the
- * Widget which was clicked on was, or what the click event was
- */
-void CopyGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- int ret;
-
- ret = SaveGameToFile(gameCopyFilename, FALSE);
- if (!ret) return;
-
- ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
- CurrentTime,
- SendGameSelection,
- NULL/* lose_ownership_proc */ ,
- NULL/* transfer_done_proc */);
-}
-
-/* function called when the data to Paste is ready */
-static void
-PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
- Atom *type, XtPointer value, unsigned long *len, int *format)
-{
- FILE* f;
- if (value == NULL || *len == 0) {
- return; /* nothing had been selected to copy */
- }
- f = fopen(gamePasteFilename, "w");
- if (f == NULL) {
- DisplayError("Can't open temp file", errno);
- return;
- }
- fwrite(value, 1, *len, f);
- fclose(f);
- XtFree(value);
- LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);
-}
-
-/* called when Paste Game button is pressed,
- * all parameters will be NULL */
-void PasteGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
- /* (XtSelectionCallbackProc) */ PasteGameCB,
- NULL, /* client_data passed to PasteGameCB */
-
- /* better to use the time field from the event that triggered the
- * call to this function, but that isn't trivial to get
- */
- CurrentTime
- );
- return;
-}
-
-
-void AutoSaveGame()
-{
- SaveGameProc(NULL, NULL, NULL, NULL);
-}
-
-
-void QuitProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ExitEvent(0);
-}
-
-void PauseProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- PauseEvent();
-}
-
-
-void MachineBlackProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- MachineBlackEvent();
-}
-
-void MachineWhiteProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- MachineWhiteEvent();
-}
-
-void AnalyzeModeProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (!first.analysisSupport) {
- char buf[MSG_SIZ];
- sprintf(buf, "%s does not support analysis", first.tidy);
- DisplayError(buf, 0);
- return;
- }
- if (!appData.showThinking)
- ShowThinkingProc(w,event,prms,nprms);
-
- AnalyzeModeEvent();
-}
-
-void AnalyzeFileProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (!first.analysisSupport) {
- char buf[MSG_SIZ];
- sprintf(buf, "%s does not support analysis", first.tidy);
- DisplayError(buf, 0);
- return;
- }
- Reset(FALSE, TRUE);
-
- if (!appData.showThinking)
- ShowThinkingProc(w,event,prms,nprms);
-
- AnalyzeFileEvent();
- FileNamePopUp("File to analyze", "", LoadGamePopUp, "rb");
- AnalysisPeriodicEvent(1);
-}
-
-void TwoMachinesProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- TwoMachinesEvent();
-}
-
-void IcsClientProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- IcsClientEvent();
-}
-
-void EditGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- EditGameEvent();
-}
-
-void EditPositionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- EditPositionEvent();
-}
-
-void TrainingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- TrainingEvent();
-}
-
-void EditCommentProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (editUp) {
- EditCommentPopDown();
- } else {
- EditCommentEvent();
- }
-}
-
-void IcsInputBoxProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (ICSInputBoxUp) {
- ICSInputBoxPopDown();
- } else {
- ICSInputBoxPopUp();
- }
-}
-
-void AcceptProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- AcceptEvent();
-}
-
-void DeclineProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- DeclineEvent();
-}
-
-void RematchProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- RematchEvent();
-}
-
-void CallFlagProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- CallFlagEvent();
-}
-
-void DrawProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- DrawEvent();
-}
-
-void AbortProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- AbortEvent();
-}
-
-void AdjournProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- AdjournEvent();
-}
-
-void ResignProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ResignEvent();
-}
-
-void EnterKeyProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (ICSInputBoxUp == True)
- ICSInputSendText();
-}
-
-void StopObservingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- StopObservingEvent();
-}
-
-void StopExaminingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- StopExaminingEvent();
-}
-
-
-void ForwardProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ForwardEvent();
-}
-
-
-void BackwardProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- BackwardEvent();
-}
-
-void ToStartProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ToStartEvent();
-}
-
-void ToEndProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- ToEndEvent();
-}
-
-void RevertProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- RevertEvent();
-}
-
-void TruncateGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- TruncateGameEvent();
-}
-void RetractMoveProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- RetractMoveEvent();
-}
-
-void MoveNowProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- MoveNowEvent();
-}
-
-
-void AlwaysQueenProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
-
- if (appData.alwaysPromoteToQueen) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
- args, 1);
-}
-
-void AnimateDraggingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.animateDragging = !appData.animateDragging;
-
- if (appData.animateDragging) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- CreateAnimVars();
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
- args, 1);
-}
-
-void AnimateMovingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.animate = !appData.animate;
-
- if (appData.animate) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- CreateAnimVars();
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
- args, 1);
-}
-
-void AutocommProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.autoComment = !appData.autoComment;
-
- if (appData.autoComment) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
- args, 1);
-}
-
-
-void AutoflagProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.autoCallFlag = !appData.autoCallFlag;
-
- if (appData.autoCallFlag) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
- args, 1);
-}
-
-void AutoflipProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.autoFlipView = !appData.autoFlipView;
-
- if (appData.autoFlipView) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),
- args, 1);
-}
-
-void AutobsProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.autoObserve = !appData.autoObserve;
-
- if (appData.autoObserve) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
- args, 1);
-}
-
-void AutoraiseProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.autoRaiseBoard = !appData.autoRaiseBoard;
-
- if (appData.autoRaiseBoard) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),
- args, 1);
-}
-
-void AutosaveProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.autoSaveGames = !appData.autoSaveGames;
-
- if (appData.autoSaveGames) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
- args, 1);
-}
-
-void BlindfoldProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.blindfold = !appData.blindfold;
-
- if (appData.blindfold) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),
- args, 1);
-
- DrawPosition(True, NULL);
-}
-
-void TestLegalityProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.testLegality = !appData.testLegality;
-
- if (appData.testLegality) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),
- args, 1);
-}
-
-
-void FlashMovesProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- if (appData.flashCount == 0) {
- appData.flashCount = 3;
- } else {
- appData.flashCount = -appData.flashCount;
- }
-
- if (appData.flashCount > 0) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),
- args, 1);
-}
-
-void FlipViewProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- flipView = !flipView;
- DrawPosition(True, NULL);
-}
-
-void GetMoveListProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.getMoveList = !appData.getMoveList;
-
- if (appData.getMoveList) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- GetMoveListEvent();
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
- args, 1);
-}
-
-#if HIGHDRAG
-void HighlightDraggingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.highlightDragging = !appData.highlightDragging;
-
- if (appData.highlightDragging) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Highlight Dragging"), args, 1);
-}
-#endif
-
-void HighlightLastMoveProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.highlightLastMove = !appData.highlightLastMove;
-
- if (appData.highlightLastMove) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Highlight Last Move"), args, 1);
-}
-
-void IcsAlarmProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.icsAlarm = !appData.icsAlarm;
-
- if (appData.icsAlarm) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.ICS Alarm"), args, 1);
-}
-
-void MoveSoundProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
-
- if (appData.ringBellAfterMoves) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
- args, 1);
-}
-
-
-void OldSaveStyleProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.oldSaveStyle = !appData.oldSaveStyle;
-
- if (appData.oldSaveStyle) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
- args, 1);
-}
-
-void PeriodicUpdatesProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- PeriodicUpdatesEvent(!appData.periodicUpdates);
-
- if (appData.periodicUpdates) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),
- args, 1);
-}
-
-void PonderNextMoveProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- PonderNextMoveEvent(!appData.ponderNextMove);
-
- if (appData.ponderNextMove) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
- args, 1);
-}
-
-void PopupExitMessageProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.popupExitMessage = !appData.popupExitMessage;
-
- if (appData.popupExitMessage) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Popup Exit Message"), args, 1);
-}
-
-void PopupMoveErrorsProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.popupMoveErrors = !appData.popupMoveErrors;
-
- if (appData.popupMoveErrors) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),
- args, 1);
-}
-
-void PremoveProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.premove = !appData.premove;
-
- if (appData.premove) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Premove"), args, 1);
-}
-
-void QuietPlayProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.quietPlay = !appData.quietPlay;
-
- if (appData.quietPlay) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
- args, 1);
-}
-
-void ShowCoordsProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- appData.showCoords = !appData.showCoords;
-
- if (appData.showCoords) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
- args, 1);
-
- DrawPosition(True, NULL);
-}
-
-void ShowThinkingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- ShowThinkingEvent(!appData.showThinking);
-
- if (appData.showThinking) {
- XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, None);
- }
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
- args, 1);
-}
-
-void InfoProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- char buf[MSG_SIZ];
- sprintf(buf, "xterm -e info --directory %s --directory . -f %s &",
- INFODIR, INFOFILE);
- system(buf);
-}
-
-void ManProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- char buf[MSG_SIZ];
- String name;
- if (nprms && *nprms > 0)
- name = prms[0];
- else
- name = "xboard";
- sprintf(buf, "xterm -e man %s &", name);
- system(buf);
-}
-
-void HintProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- HintEvent();
-}
-
-void BookProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- BookEvent();
-}
-
-void AboutProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- char buf[MSG_SIZ];
-#if ZIPPY
- char *zippy = " (with Zippy code)";
-#else
- char *zippy = "";
-#endif
- sprintf(buf, "%s%s\n\n%s\n%s\n\n%s%s\n%s",
- programVersion, zippy,
- "Copyright 1991 Digital Equipment Corporation",
- "Enhancements Copyright 1992-2001 Free Software Foundation",
- PRODUCT, " is free software and carries NO WARRANTY;",
- "see the file COPYING for more information.");
- ErrorPopUp("About XBoard", buf, FALSE);
-}
-
-void DebugProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- appData.debugMode = !appData.debugMode;
-}
-
-void AboutGameProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- AboutGameEvent();
-}
-
-void NothingProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- return;
-}
-
-void Iconify(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- Arg args[16];
-
- fromX = fromY = -1;
- XtSetArg(args[0], XtNiconic, True);
- XtSetValues(shellWidget, args, 1);
-}
-
-void DisplayMessage(message, extMessage)
- char *message, *extMessage;
-{
- char buf[MSG_SIZ];
- Arg arg;
-
- if (extMessage) {
- if (*message) {
- sprintf(buf, "%s %s", message, extMessage);
- message = buf;
- } else {
- message = extMessage;
- }
- }
- XtSetArg(arg, XtNlabel, message);
- XtSetValues(messageWidget, &arg, 1);
-}
-
-void DisplayTitle(text)
- char *text;
-{
- Arg args[16];
- int i;
- char title[MSG_SIZ];
- char icon[MSG_SIZ];
-
- if (text == NULL) text = "";
-
- if (appData.titleInWindow) {
- i = 0;
- XtSetArg(args[i], XtNlabel, text); i++;
- XtSetValues(titleWidget, args, i);
- }
-
- if (*text != NULLCHAR) {
- strcpy(icon, text);
- strcpy(title, text);
- } else if (appData.icsActive) {
- sprintf(icon, "%s", appData.icsHost);
- sprintf(title, "%s: %s", programName, appData.icsHost);
- } else if (appData.cmailGameName[0] != NULLCHAR) {
- sprintf(icon, "%s", "CMail");
- sprintf(title, "%s: %s", programName, "CMail");
- } else if (appData.noChessProgram) {
- strcpy(icon, programName);
- strcpy(title, programName);
- } else {
- strcpy(icon, first.tidy);
- sprintf(title, "%s: %s", programName, first.tidy);
- }
- i = 0;
- XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++;
- XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++;
- XtSetValues(shellWidget, args, i);
-}
-
-
-void DisplayError(message, error)
- String message;
- int error;
-{
- char buf[MSG_SIZ];
-
- if (error == 0) {
- if (appData.debugMode || appData.matchMode) {
- fprintf(stderr, "%s: %s\n", programName, message);
- }
- } else {
- if (appData.debugMode || appData.matchMode) {
- fprintf(stderr, "%s: %s: %s\n",
- programName, message, strerror(error));
- }
- sprintf(buf, "%s: %s", message, strerror(error));
- message = buf;
- }
- ErrorPopUp("Error", message, FALSE);
-}
-
-
-void DisplayMoveError(message)
- String message;
-{
- fromX = fromY = -1;
- ClearHighlights();
- DrawPosition(FALSE, NULL);
- if (appData.debugMode || appData.matchMode) {
- fprintf(stderr, "%s: %s\n", programName, message);
- }
- if (appData.popupMoveErrors) {
- ErrorPopUp("Error", message, FALSE);
- } else {
- DisplayMessage(message, "");
- }
-}
-
-
-void DisplayFatalError(message, error, status)
- String message;
- int error, status;
-{
- char buf[MSG_SIZ];
-
- errorExitStatus = status;
- if (error == 0) {
- fprintf(stderr, "%s: %s\n", programName, message);
- } else {
- fprintf(stderr, "%s: %s: %s\n",
- programName, message, strerror(error));
- sprintf(buf, "%s: %s", message, strerror(error));
- message = buf;
- }
- if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
- ErrorPopUp(status ? "Fatal Error" : "Exiting", message, TRUE);
- } else {
- ExitEvent(status);
- }
-}
-
-void DisplayInformation(message)
- String message;
-{
- ErrorPopDown();
- ErrorPopUp("Information", message, TRUE);
-}
-
-void DisplayNote(message)
- String message;
-{
- ErrorPopDown();
- ErrorPopUp("Note", message, FALSE);
-}
-
-static int
-NullXErrorCheck(dpy, error_event)
- Display *dpy;
- XErrorEvent *error_event;
-{
- return 0;
-}
-
-void DisplayIcsInteractionTitle(message)
- String message;
-{
- if (oldICSInteractionTitle == NULL) {
- /* Magic to find the old window title, adapted from vim */
- char *wina = getenv("WINDOWID");
- if (wina != NULL) {
- Window win = (Window) atoi(wina);
- Window root, parent, *children;
- unsigned int nchildren;
- int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);
- for (;;) {
- if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
- if (!XQueryTree(xDisplay, win, &root, &parent,
- &children, &nchildren)) break;
- if (children) XFree((void *)children);
- if (parent == root || parent == 0) break;
- win = parent;
- }
- XSetErrorHandler(oldHandler);
- }
- if (oldICSInteractionTitle == NULL) {
- oldICSInteractionTitle = "xterm";
- }
- }
- printf("\033]0;%s\007", message);
- fflush(stdout);
-}
-
-char pendingReplyPrefix[MSG_SIZ];
-ProcRef pendingReplyPR;
-
-void AskQuestionProc(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- if (*nprms != 4) {
- fprintf(stderr, "AskQuestionProc needed 4 parameters, got %d\n",
- *nprms);
- return;
- }
- AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);
-}
-
-void AskQuestionPopDown()
-{
- if (!askQuestionUp) return;
- XtPopdown(askQuestionShell);
- XtDestroyWidget(askQuestionShell);
- askQuestionUp = False;
-}
-
-void AskQuestionReplyAction(w, event, prms, nprms)
- Widget w;
- XEvent *event;
- String *prms;
- Cardinal *nprms;
-{
- char buf[MSG_SIZ];
- int err;
- String reply;
-
- reply = XawDialogGetValueString(w = XtParent(w));
- strcpy(buf, pendingReplyPrefix);
- if (*buf) strcat(buf, " ");
- strcat(buf, reply);
- strcat(buf, "\n");
- OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
- AskQuestionPopDown();
-
- if (err) DisplayFatalError("Error writing to chess program", err, 0);
-}
-
-void AskQuestionCallback(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
-{
- String name;
- Arg args[16];
-
- XtSetArg(args[0], XtNlabel, &name);
- XtGetValues(w, args, 1);
-
- if (strcmp(name, "cancel") == 0) {
- AskQuestionPopDown();
- } else {
- AskQuestionReplyAction(w, NULL, NULL, NULL);
- }
-}
-
-void AskQuestion(title, question, replyPrefix, pr)
- char *title, *question, *replyPrefix;
- ProcRef pr;
-{
- Arg args[16];
- Widget popup, layout, dialog, edit;
- Window root, child;
- int x, y, i;
- int win_x, win_y;
- unsigned int mask;
-
- strcpy(pendingReplyPrefix, replyPrefix);
- pendingReplyPR = pr;
-
- i = 0;
- XtSetArg(args[i], XtNresizable, True); i++;
- XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
- askQuestionShell = popup =
- XtCreatePopupShell(title, transientShellWidgetClass,
- shellWidget, args, i);
-
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, popup,
- layoutArgs, XtNumber(layoutArgs));
-
- i = 0;
- XtSetArg(args[i], XtNlabel, question); i++;
- XtSetArg(args[i], XtNvalue, ""); i++;
- XtSetArg(args[i], XtNborderWidth, 0); i++;
- dialog = XtCreateManagedWidget("question", dialogWidgetClass,
- layout, args, i);
-
- XawDialogAddButton(dialog, "enter", AskQuestionCallback,
- (XtPointer) dialog);
- XawDialogAddButton(dialog, "cancel", AskQuestionCallback,
- (XtPointer) dialog);
-
- XtRealizeWidget(popup);
- CatchDeleteWindow(popup, "AskQuestionPopDown");
-
- XQueryPointer(xDisplay, xBoardWindow, &root, &child,
- &x, &y, &win_x, &win_y, &mask);
-
- XtSetArg(args[0], XtNx, x - 10);
- XtSetArg(args[1], XtNy, y - 30);
- XtSetValues(popup, args, 2);
-
- XtPopup(popup, XtGrabExclusive);
- askQuestionUp = True;
-
- edit = XtNameToWidget(dialog, "*value");
- XtSetKeyboardFocus(popup, edit);
-}
-
-
-void
-PlaySound(name)
- char *name;
-{
- if (*name == NULLCHAR) {
- return;
- } else if (strcmp(name, "$") == 0) {
- putc(BELLCHAR, stderr);
- } else {
- char buf[2048];
- sprintf(buf, "%s '%s' &", appData.soundProgram, name);
- system(buf);
- }
-}
-
-void
-RingBell()
-{
- PlaySound(appData.soundMove);
-}
-
-void
-PlayIcsWinSound()
-{
- PlaySound(appData.soundIcsWin);
-}
-
-void
-PlayIcsLossSound()
-{
- PlaySound(appData.soundIcsLoss);
-}
-
-void
-PlayIcsDrawSound()
-{
- PlaySound(appData.soundIcsDraw);
-}
-
-void
-PlayIcsUnfinishedSound()
-{
- PlaySound(appData.soundIcsUnfinished);
-}
-
-void
-PlayAlarmSound()
-{
- PlaySound(appData.soundIcsAlarm);
-}
-
-void
-EchoOn()
-{
- system("stty echo");
-}
-
-void
-EchoOff()
-{
- system("stty -echo");
-}
-
-void
-Colorize(cc, continuation)
- ColorClass cc;
- int continuation;
-{
- char buf[MSG_SIZ];
- int count, outCount, error;
-
- if (textColors[(int)cc].bg > 0) {
- if (textColors[(int)cc].fg > 0) {
- sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].fg, textColors[(int)cc].bg);
- } else {
- sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].bg);
- }
- } else {
- if (textColors[(int)cc].fg > 0) {
- sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].fg);
- } else {
- sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);
- }
- }
- count = strlen(buf);
- outCount = OutputToProcess(NoProc, buf, count, &error);
- if (outCount < count) {
- DisplayFatalError("Error writing to display", error, 1);
- }
-
- if (continuation) return;
- switch (cc) {
- case ColorShout:
- PlaySound(appData.soundShout);
- break;
- case ColorSShout:
- PlaySound(appData.soundSShout);
- break;
- case ColorChannel1:
- PlaySound(appData.soundChannel1);
- break;
- case ColorChannel:
- PlaySound(appData.soundChannel);
- break;
- case ColorKibitz:
- PlaySound(appData.soundKibitz);
- break;
- case ColorTell:
- PlaySound(appData.soundTell);
- break;
- case ColorChallenge:
- PlaySound(appData.soundChallenge);
- break;
- case ColorRequest:
- PlaySound(appData.soundRequest);
- break;
- case ColorSeek:
- PlaySound(appData.soundSeek);
- break;
- case ColorNormal:
- case ColorNone:
- default:
- break;
- }
-}
-
-char *UserName()
-{
- return getpwuid(getuid())->pw_name;
-}
-
-static char *ExpandPathName(path)
- char *path;
-{
- static char static_buf[2000];
- char *d, *s, buf[2000];
- struct passwd *pwd;
-
- s = path;
- d = static_buf;
-
- while (*s && isspace(*s))
- ++s;
-
- if (!*s) {
- *d = 0;
- return static_buf;
- }
-
- if (*s == '~') {
- if (*(s+1) == '/') {
- strcpy(d, getpwuid(getuid())->pw_dir);
- strcat(d, s+1);
- }
- else {
- strcpy(buf, s+1);
- *strchr(buf, '/') = 0;
- pwd = getpwnam(buf);
- if (!pwd)
- {
- fprintf(stderr, "ERROR: Unknown user %s (in path %s)\n",
- buf, path);
- return NULL;
- }
- strcpy(d, pwd->pw_dir);
- strcat(d, strchr(s+1, '/'));
- }
- }
- else
- strcpy(d, s);
-
- return static_buf;
-}
-
-char *HostName()
-{
- static char host_name[MSG_SIZ];
-
-#if HAVE_GETHOSTNAME
- gethostname(host_name, MSG_SIZ);
- return host_name;
-#else /* not HAVE_GETHOSTNAME */
-# if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
- sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
- return host_name;
-# else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
- return "localhost";
-# endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
-#endif /* not HAVE_GETHOSTNAME */
-}
-
-XtIntervalId delayedEventTimerXID = 0;
-DelayedEventCallback delayedEventCallback = 0;
-
-void
-FireDelayedEvent()
-{
- delayedEventTimerXID = 0;
- delayedEventCallback();
-}
-
-void
-ScheduleDelayedEvent(cb, millisec)
- DelayedEventCallback cb; long millisec;
-{
- delayedEventCallback = cb;
- delayedEventTimerXID =
- XtAppAddTimeOut(appContext, millisec,
- (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
-}
-
-DelayedEventCallback
-GetDelayedEvent()
-{
- if (delayedEventTimerXID) {
- return delayedEventCallback;
- } else {
- return NULL;
- }
-}
-
-void
-CancelDelayedEvent()
-{
- if (delayedEventTimerXID) {
- XtRemoveTimeOut(delayedEventTimerXID);
- delayedEventTimerXID = 0;
- }
-}
-
-XtIntervalId loadGameTimerXID = 0;
-
-int LoadGameTimerRunning()
-{
- return loadGameTimerXID != 0;
-}
-
-int StopLoadGameTimer()
-{
- if (loadGameTimerXID != 0) {
- XtRemoveTimeOut(loadGameTimerXID);
- loadGameTimerXID = 0;
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-void
-LoadGameTimerCallback(arg, id)
- XtPointer arg;
- XtIntervalId *id;
-{
- loadGameTimerXID = 0;
- AutoPlayGameLoop();
-}
-
-void
-StartLoadGameTimer(millisec)
- long millisec;
-{
- loadGameTimerXID =
- XtAppAddTimeOut(appContext, millisec,
- (XtTimerCallbackProc) LoadGameTimerCallback,
- (XtPointer) 0);
-}
-
-XtIntervalId analysisClockXID = 0;
-
-void
-AnalysisClockCallback(arg, id)
- XtPointer arg;
- XtIntervalId *id;
-{
- if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
- AnalysisPeriodicEvent(0);
- StartAnalysisClock();
- }
-}
-
-void
-StartAnalysisClock()
-{
- analysisClockXID =
- XtAppAddTimeOut(appContext, 2000,
- (XtTimerCallbackProc) AnalysisClockCallback,
- (XtPointer) 0);
-}
-
-XtIntervalId clockTimerXID = 0;
-
-int ClockTimerRunning()
-{
- return clockTimerXID != 0;
-}
-
-int StopClockTimer()
-{
- if (clockTimerXID != 0) {
- XtRemoveTimeOut(clockTimerXID);
- clockTimerXID = 0;
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-void
-ClockTimerCallback(arg, id)
- XtPointer arg;
- XtIntervalId *id;
-{
- clockTimerXID = 0;
- DecrementClocks();
-}
-
-void
-StartClockTimer(millisec)
- long millisec;
-{
- clockTimerXID =
- XtAppAddTimeOut(appContext, millisec,
- (XtTimerCallbackProc) ClockTimerCallback,
- (XtPointer) 0);
-}
-
-void
-DisplayTimerLabel(w, color, timer, highlight)
- Widget w;
- char *color;
- long timer;
- int highlight;
-{
- char buf[MSG_SIZ];
- Arg args[16];
-
- if (appData.clockMode) {
- sprintf(buf, "%s: %s", color, TimeString(timer));
- XtSetArg(args[0], XtNlabel, buf);
- } else {
- sprintf(buf, "%s ", color);
- XtSetArg(args[0], XtNlabel, buf);
- }
-
- if (highlight) {
- XtSetArg(args[1], XtNbackground, timerForegroundPixel);
- XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
- } else {
- XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
- XtSetArg(args[2], XtNforeground, timerForegroundPixel);
- }
-
- XtSetValues(w, args, 3);
-}
-
-void
-DisplayWhiteClock(timeRemaining, highlight)
- long timeRemaining;
- int highlight;
-{
- Arg args[16];
- DisplayTimerLabel(whiteTimerWidget, "White", timeRemaining, highlight);
- if (highlight && iconPixmap == bIconPixmap) {
- iconPixmap = wIconPixmap;
- XtSetArg(args[0], XtNiconPixmap, iconPixmap);
- XtSetValues(shellWidget, args, 1);
- }
-}
-
-void
-DisplayBlackClock(timeRemaining, highlight)
- long timeRemaining;
- int highlight;
-{
- Arg args[16];
- DisplayTimerLabel(blackTimerWidget, "Black", timeRemaining, highlight);
- if (highlight && iconPixmap == wIconPixmap) {
- iconPixmap = bIconPixmap;
- XtSetArg(args[0], XtNiconPixmap, iconPixmap);
- XtSetValues(shellWidget, args, 1);
- }
-}
-
-#define CPNone 0
-#define CPReal 1
-#define CPComm 2
-#define CPSock 3
-#define CPLoop 4
-typedef int CPKind;
-
-typedef struct {
- CPKind kind;
- int pid;
- int fdTo, fdFrom;
-} ChildProc;
-
-
-int StartChildProcess(cmdLine, dir, pr)
- char *cmdLine;
- char *dir;
- ProcRef *pr;
-{
- char *argv[64], *p;
- int i, pid;
- int to_prog[2], from_prog[2];
- ChildProc *cp;
- char buf[MSG_SIZ];
-
- if (appData.debugMode) {
- fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
- }
-
- /* We do NOT feed the cmdLine to the shell; we just
- parse it into blank-separated arguments in the
- most simple-minded way possible.
- */
- i = 0;
- strcpy(buf, cmdLine);
- p = buf;
- for (;;) {
- argv[i++] = p;
- p = strchr(p, ' ');
- if (p == NULL) break;
- *p++ = NULLCHAR;
- }
- argv[i] = NULL;
-
- SetUpChildIO(to_prog, from_prog);
-
- if ((pid = fork()) == 0) {
- /* Child process */
- dup2(to_prog[0], 0);
- dup2(from_prog[1], 1);
- close(to_prog[0]);
- close(to_prog[1]);
- close(from_prog[0]);
- close(from_prog[1]);
- dup2(1, fileno(stderr)); /* force stderr to the pipe */
-
- if (dir[0] != NULLCHAR && chdir(dir) != 0) {
- perror(dir);
- exit(1);
- }
-
- execvp(argv[0], argv);
-
- /* If we get here, exec failed */
- perror(argv[0]);
- exit(1);
- }
-
- /* Parent process */
- close(to_prog[0]);
- close(from_prog[1]);
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPReal;
- cp->pid = pid;
- cp->fdFrom = from_prog[0];
- cp->fdTo = to_prog[1];
- *pr = (ProcRef) cp;
- return 0;
-}
-
-void
-DestroyChildProcess(pr, signal)
- ProcRef pr;
- int signal;
-{
- ChildProc *cp = (ChildProc *) pr;
-
- if (cp->kind != CPReal) return;
- cp->kind = CPNone;
- if (signal) {
- kill(cp->pid, SIGTERM);
- }
- /* Process is exiting either because of the kill or because of
- a quit command sent by the backend; either way, wait for it to die.
- */
- wait((int *) 0);
- close(cp->fdFrom);
- close(cp->fdTo);
-}
-
-void
-InterruptChildProcess(pr)
- ProcRef pr;
-{
- ChildProc *cp = (ChildProc *) pr;
-
- if (cp->kind != CPReal) return;
- (void) kill(cp->pid, SIGINT); /* stop it thinking */
-}
-
-int OpenTelnet(host, port, pr)
- char *host;
- char *port;
- ProcRef *pr;
-{
- char cmdLine[MSG_SIZ];
-
- if (port[0] == NULLCHAR) {
- sprintf(cmdLine, "%s %s", appData.telnetProgram, host);
- } else {
- sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);
- }
- return StartChildProcess(cmdLine, "", pr);
-}
-
-int OpenTCP(host, port, pr)
- char *host;
- char *port;
- ProcRef *pr;
-{
-#if OMIT_SOCKETS
- DisplayFatalError("Socket support is not configured in", 0, 2);
-#else /* !OMIT_SOCKETS */
- int s;
- struct sockaddr_in sa;
- struct hostent *hp;
- unsigned short uport;
- ChildProc *cp;
-
- if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
- return errno;
- }
-
- memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
- sa.sin_family = AF_INET;
- sa.sin_addr.s_addr = INADDR_ANY;
- uport = (unsigned short) 0;
- sa.sin_port = htons(uport);
- if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
- return errno;
- }
-
- memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
- if (!(hp = gethostbyname(host))) {
- int b0, b1, b2, b3;
- if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
- hp = (struct hostent *) calloc(1, sizeof(struct hostent));
- hp->h_addrtype = AF_INET;
- hp->h_length = 4;
- hp->h_addr_list = (char **) calloc(2, sizeof(char *));
- hp->h_addr_list[0] = (char *) malloc(4);
- hp->h_addr_list[0][0] = b0;
- hp->h_addr_list[0][1] = b1;
- hp->h_addr_list[0][2] = b2;
- hp->h_addr_list[0][3] = b3;
- } else {
- return ENOENT;
- }
- }
- sa.sin_family = hp->h_addrtype;
- uport = (unsigned short) atoi(port);
- sa.sin_port = htons(uport);
- memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
-
- if (connect(s, (struct sockaddr *) &sa,
- sizeof(struct sockaddr_in)) < 0) {
- return errno;
- }
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPSock;
- cp->pid = 0;
- cp->fdFrom = s;
- cp->fdTo = s;
- *pr = (ProcRef) cp;
-
-#endif /* !OMIT_SOCKETS */
-
- return 0;
-}
-
-int OpenCommPort(name, pr)
- char *name;
- ProcRef *pr;
-{
- int fd;
- ChildProc *cp;
-
- fd = open(name, 2, 0);
- if (fd < 0) return errno;
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPComm;
- cp->pid = 0;
- cp->fdFrom = fd;
- cp->fdTo = fd;
- *pr = (ProcRef) cp;
-
- return 0;
-}
-
-int OpenLoopback(pr)
- ProcRef *pr;
-{
- ChildProc *cp;
- int to[2], from[2];
-
- SetUpChildIO(to, from);
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPLoop;
- cp->pid = 0;
- cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */
- cp->fdTo = to[1];
- *pr = (ProcRef) cp;
-
- return 0;
-}
-
-int OpenRcmd(host, user, cmd, pr)
- char *host, *user, *cmd;
- ProcRef *pr;
-{
- DisplayFatalError("internal rcmd not implemented for Unix", 0, 1);
- return -1;
-}
-
-#define INPUT_SOURCE_BUF_SIZE 8192
-
-typedef struct {
- CPKind kind;
- int fd;
- int lineByLine;
- char *unused;
- InputCallback func;
- XtInputId xid;
- char buf[INPUT_SOURCE_BUF_SIZE];
- VOIDSTAR closure;
-} InputSource;
-
-void
-DoInputCallback(closure, source, xid)
- caddr_t closure;
- int *source;
- XtInputId *xid;
-{
- InputSource *is = (InputSource *) closure;
- int count;
- int error;
- char *p, *q;
-
- if (is->lineByLine) {
- count = read(is->fd, is->unused,
- INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
- if (count <= 0) {
- (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
- return;
- }
- is->unused += count;
- p = is->buf;
- while (p < is->unused) {
- q = memchr(p, '\n', is->unused - p);
- if (q == NULL) break;
- q++;
- (is->func)(is, is->closure, p, q - p, 0);
- p = q;
- }
- q = is->buf;
- while (p < is->unused) {
- *q++ = *p++;
- }
- is->unused = q;
- } else {
- count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
- if (count == -1)
- error = errno;
- else
- error = 0;
- (is->func)(is, is->closure, is->buf, count, error);
- }
-}
-
-InputSourceRef AddInputSource(pr, lineByLine, func, closure)
- ProcRef pr;
- int lineByLine;
- InputCallback func;
- VOIDSTAR closure;
-{
- InputSource *is;
- ChildProc *cp = (ChildProc *) pr;
-
- is = (InputSource *) calloc(1, sizeof(InputSource));
- is->lineByLine = lineByLine;
- is->func = func;
- if (pr == NoProc) {
- is->kind = CPReal;
- is->fd = fileno(stdin);
- } else {
- is->kind = cp->kind;
- is->fd = cp->fdFrom;
- }
- if (lineByLine) {
- is->unused = is->buf;
- }
-
- is->xid = XtAppAddInput(appContext, is->fd,
- (XtPointer) (XtInputReadMask),
- (XtInputCallbackProc) DoInputCallback,
- (XtPointer) is);
- is->closure = closure;
- return (InputSourceRef) is;
-}
-
-void
-RemoveInputSource(isr)
- InputSourceRef isr;
-{
- InputSource *is = (InputSource *) isr;
-
- if (is->xid == 0) return;
- XtRemoveInput(is->xid);
- is->xid = 0;
-}
-
-int OutputToProcess(pr, message, count, outError)
- ProcRef pr;
- char *message;
- int count;
- int *outError;
-{
- ChildProc *cp = (ChildProc *) pr;
- int outCount;
-
- if (pr == NoProc)
- outCount = fwrite(message, 1, count, stdout);
- else
- outCount = write(cp->fdTo, message, count);
-
- if (outCount == -1)
- *outError = errno;
- else
- *outError = 0;
-
- return outCount;
-}
-
-/* Output message to process, with "ms" milliseconds of delay
- between each character. This is needed when sending the logon
- script to ICC, which for some reason doesn't like the
- instantaneous send. */
-int OutputToProcessDelayed(pr, message, count, outError, msdelay)
- ProcRef pr;
- char *message;
- int count;
- int *outError;
- long msdelay;
-{
- ChildProc *cp = (ChildProc *) pr;
- int outCount = 0;
- int r;
-
- while (count--) {
- r = write(cp->fdTo, message++, 1);
- if (r == -1) {
- *outError = errno;
- return outCount;
- }
- ++outCount;
- if (msdelay >= 0)
- TimeDelay(msdelay);
- }
-
- return outCount;
-}
-
-/**** Animation code by Hugh Fisher, DCS, ANU.
-
- Known problem: if a window overlapping the board is
- moved away while a piece is being animated underneath,
- the newly exposed area won't be updated properly.
- I can live with this.
-
- Known problem: if you look carefully at the animation
- of pieces in mono mode, they are being drawn as solid
- shapes without interior detail while moving. Fixing
- this would be a major complication for minimal return.
-****/
-
-/* Masks for XPM pieces. Black and white pieces can have
- different shapes, but in the interest of retaining my
- sanity pieces must have the same outline on both light
- and dark squares, and all pieces must use the same
- background square colors/images. */
-
-static void
-CreateAnimMasks (pieceDepth)
- int pieceDepth;
-{
- ChessSquare piece;
- Pixmap buf;
- GC bufGC, maskGC;
- int kind, n;
- unsigned long plane;
- XGCValues values;
-
- /* Need a bitmap just to get a GC with right depth */
- buf = XCreatePixmap(xDisplay, xBoardWindow,
- 8, 8, 1);
- values.foreground = 1;
- values.background = 0;
- /* Don't use XtGetGC, not read only */
- maskGC = XCreateGC(xDisplay, buf,
- GCForeground | GCBackground, &values);
- XFreePixmap(xDisplay, buf);
-
- buf = XCreatePixmap(xDisplay, xBoardWindow,
- squareSize, squareSize, pieceDepth);
- values.foreground = XBlackPixel(xDisplay, xScreen);
- values.background = XWhitePixel(xDisplay, xScreen);
- bufGC = XCreateGC(xDisplay, buf,
- GCForeground | GCBackground, &values);
-
- for (piece = WhitePawn; piece <= BlackKing; piece++) {
- /* Begin with empty mask */
- xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
- squareSize, squareSize, 1);
- XSetFunction(xDisplay, maskGC, GXclear);
- XFillRectangle(xDisplay, xpmMask[piece], maskGC,
- 0, 0, squareSize, squareSize);
-
- /* Take a copy of the piece */
- if (White(piece))
- kind = 0;
- else
- kind = 2;
- XSetFunction(xDisplay, bufGC, GXcopy);
- XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % 6],
- buf, bufGC,
- 0, 0, squareSize, squareSize, 0, 0);
-
- /* XOR the background (light) over the piece */
- XSetFunction(xDisplay, bufGC, GXxor);
- if (useImageSqs)
- XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
- 0, 0, squareSize, squareSize, 0, 0);
- else {
- XSetForeground(xDisplay, bufGC, lightSquareColor);
- XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
- }
-
- /* We now have an inverted piece image with the background
- erased. Construct mask by just selecting all the non-zero
- pixels - no need to reconstruct the original image. */
- XSetFunction(xDisplay, maskGC, GXor);
- plane = 1;
- /* Might be quicker to download an XImage and create bitmap
- data from it rather than this N copies per piece, but it
- only takes a fraction of a second and there is a much
- longer delay for loading the pieces. */
- for (n = 0; n < pieceDepth; n ++) {
- XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
- 0, 0, squareSize, squareSize,
- 0, 0, plane);
- plane = plane << 1;
- }
- }
- /* Clean up */
- XFreePixmap(xDisplay, buf);
- XFreeGC(xDisplay, bufGC);
- XFreeGC(xDisplay, maskGC);
-}
-
-static void
-InitAnimState (anim, info)
- AnimState * anim;
- XWindowAttributes * info;
-{
- XtGCMask mask;
- XGCValues values;
-
- /* Each buffer is square size, same depth as window */
- anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
- squareSize, squareSize, info->depth);
- anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
- squareSize, squareSize, info->depth);
-
- /* Create a plain GC for blitting */
- mask = GCForeground | GCBackground | GCFunction |
- GCPlaneMask | GCGraphicsExposures;
- values.foreground = XBlackPixel(xDisplay, xScreen);
- values.background = XWhitePixel(xDisplay, xScreen);
- values.function = GXcopy;
- values.plane_mask = AllPlanes;
- values.graphics_exposures = False;
- anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
-
- /* Piece will be copied from an existing context at
- the start of each new animation/drag. */
- anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
-
- /* Outline will be a read-only copy of an existing */
- anim->outlineGC = None;
-}
-
-static void
-CreateAnimVars ()
-{
- static int done = 0;
- XWindowAttributes info;
-
- if (done) return;
- done = 1;
- XGetWindowAttributes(xDisplay, xBoardWindow, &info);
-
- InitAnimState(&game, &info);
- InitAnimState(&player, &info);
-
- /* For XPM pieces, we need bitmaps to use as masks. */
- if (useImages)
- CreateAnimMasks(info.depth);
-}
-
-#ifndef HAVE_USLEEP
-
-static Boolean frameWaiting;
-
-static RETSIGTYPE FrameAlarm (sig)
- int sig;
-{
- frameWaiting = False;
- /* In case System-V style signals. Needed?? */
- signal(SIGALRM, FrameAlarm);
-}
-
-static void
-FrameDelay (time)
- int time;
-{
- struct itimerval delay;
-
- XSync(xDisplay, False);
-
- if (time > 0) {
- frameWaiting = True;
- signal(SIGALRM, FrameAlarm);
- delay.it_interval.tv_sec =
- delay.it_value.tv_sec = time / 1000;
- delay.it_interval.tv_usec =
- delay.it_value.tv_usec = (time % 1000) * 1000;
- setitimer(ITIMER_REAL, &delay, NULL);
-#if 0
- /* Ugh -- busy-wait! --tpm */
- while (frameWaiting);
-#else
- while (frameWaiting) pause();
-#endif
- delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
- delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &delay, NULL);
- }
-}
-
-#else
-
-static void
-FrameDelay (time)
- int time;
-{
- XSync(xDisplay, False);
- if (time > 0)
- usleep(time * 1000);
-}
-
-#endif
-
-/* Convert board position to corner of screen rect and color */
-
-static void
-ScreenSquare(column, row, pt, color)
- int column; int row; XPoint * pt; int * color;
-{
- if (flipView) {
- pt->x = lineGap + ((BOARD_SIZE-1)-column) * (squareSize + lineGap);
- pt->y = lineGap + row * (squareSize + lineGap);
- } else {
- pt->x = lineGap + column * (squareSize + lineGap);
- pt->y = lineGap + ((BOARD_SIZE-1)-row) * (squareSize + lineGap);
- }
- *color = ((column + row) % 2) == 1;
-}
-
-/* Convert window coords to square */
-
-static void
-BoardSquare(x, y, column, row)
- int x; int y; int * column; int * row;
-{
- *column = EventToSquare(x, BOARD_SIZE);
- if (flipView && *column >= 0)
- *column = BOARD_SIZE - 1 - *column;
- *row = EventToSquare(y, BOARD_SIZE);
- if (!flipView && *row >= 0)
- *row = BOARD_SIZE - 1 - *row;
-}
-
-/* Utilities */
-
-#undef Max /* just in case */
-#undef Min
-#define Max(a, b) ((a) > (b) ? (a) : (b))
-#define Min(a, b) ((a) < (b) ? (a) : (b))
-
-static void
-SetRect(rect, x, y, width, height)
- XRectangle * rect; int x; int y; int width; int height;
-{
- rect->x = x;
- rect->y = y;
- rect->width = width;
- rect->height = height;
-}
-
-/* Test if two frames overlap. If they do, return
- intersection rect within old and location of
- that rect within new. */
-
-static Boolean
-Intersect(old, new, size, area, pt)
- XPoint * old; XPoint * new;
- int size; XRectangle * area; XPoint * pt;
-{
- if (old->x > new->x + size || new->x > old->x + size ||
- old->y > new->y + size || new->y > old->y + size) {
- return False;
- } else {
- SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0),
- size - abs(old->x - new->x), size - abs(old->y - new->y));
- pt->x = Max(old->x - new->x, 0);
- pt->y = Max(old->y - new->y, 0);
- return True;
- }
-}
-
-/* For two overlapping frames, return the rect(s)
- in the old that do not intersect with the new. */
-
-static void
-CalcUpdateRects(old, new, size, update, nUpdates)
- XPoint * old; XPoint * new; int size;
- XRectangle update[]; int * nUpdates;
-{
- int count;
-
- /* If old = new (shouldn't happen) then nothing to draw */
- if (old->x == new->x && old->y == new->y) {
- *nUpdates = 0;
- return;
- }
- /* Work out what bits overlap. Since we know the rects
- are the same size we don't need a full intersect calc. */
- count = 0;
- /* Top or bottom edge? */
- if (new->y > old->y) {
- SetRect(&(update[count]), old->x, old->y, size, new->y - old->y);
- count ++;
- } else if (old->y > new->y) {
- SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y),
- size, old->y - new->y);
- count ++;
- }
- /* Left or right edge - don't overlap any update calculated above. */
- if (new->x > old->x) {
- SetRect(&(update[count]), old->x, Max(new->y, old->y),
- new->x - old->x, size - abs(new->y - old->y));
- count ++;
- } else if (old->x > new->x) {
- SetRect(&(update[count]), new->x + size, Max(new->y, old->y),
- old->x - new->x, size - abs(new->y - old->y));
- count ++;
- }
- /* Done */
- *nUpdates = count;
-}
-
-/* Generate a series of frame coords from start->mid->finish.
- The movement rate doubles until the half way point is
- reached, then halves back down to the final destination,
- which gives a nice slow in/out effect. The algorithmn
- may seem to generate too many intermediates for short
- moves, but remember that the purpose is to attract the
- viewers attention to the piece about to be moved and
- then to where it ends up. Too few frames would be less
- noticeable. */
-
-static void
-Tween(start, mid, finish, factor, frames, nFrames)
- XPoint * start; XPoint * mid;
- XPoint * finish; int factor;
- XPoint frames[]; int * nFrames;
-{
- int fraction, n, count;
-
- count = 0;
-
- /* Slow in, stepping 1/16th, then 1/8th, ... */
- fraction = 1;
- for (n = 0; n < factor; n++)
- fraction *= 2;
- for (n = 0; n < factor; n++) {
- frames[count].x = start->x + (mid->x - start->x) / fraction;
- frames[count].y = start->y + (mid->y - start->y) / fraction;
- count ++;
- fraction = fraction / 2;
- }
-
- /* Midpoint */
- frames[count] = *mid;
- count ++;
-
- /* Slow out, stepping 1/2, then 1/4, ... */
- fraction = 2;
- for (n = 0; n < factor; n++) {
- frames[count].x = finish->x - (finish->x - mid->x) / fraction;
- frames[count].y = finish->y - (finish->y - mid->y) / fraction;
- count ++;
- fraction = fraction * 2;
- }
- *nFrames = count;
-}
-
-/* Draw a piece on the screen without disturbing what's there */
-
-static void
-SelectGCMask(piece, clip, outline, mask)
- ChessSquare piece; GC * clip; GC * outline; Pixmap * mask;
-{
- GC source;
-
- /* Bitmap for piece being moved. */
- if (appData.monoMode) {
- *mask = *pieceToSolid(piece);
- } else if (useImages) {
-#if HAVE_LIBXPM
- *mask = xpmMask[piece];
-#else
- *mask = ximMaskPm[piece%6];
-#endif
- } else {
- *mask = *pieceToSolid(piece);
- }
-
- /* GC for piece being moved. Square color doesn't matter, but
- since it gets modified we make a copy of the original. */
- if (White(piece)) {
- if (appData.monoMode)
- source = bwPieceGC;
- else
- source = wlPieceGC;
- } else {
- if (appData.monoMode)
- source = wbPieceGC;
- else
- source = blPieceGC;
- }
- XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
-
- /* Outline only used in mono mode and is not modified */
- if (White(piece))
- *outline = bwPieceGC;
- else
- *outline = wbPieceGC;
-}
-
-static void
-OverlayPiece(piece, clip, outline, dest)
- ChessSquare piece; GC clip; GC outline; Drawable dest;
-{
- int kind;
-
- if (!useImages) {
- /* Draw solid rectangle which will be clipped to shape of piece */
- XFillRectangle(xDisplay, dest, clip,
- 0, 0, squareSize, squareSize);
- if (appData.monoMode)
- /* Also draw outline in contrasting color for black
- on black / white on white cases */
- XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
- 0, 0, squareSize, squareSize, 0, 0, 1);
- } else {
- /* Copy the piece */
- if (White(piece))
- kind = 0;
- else
- kind = 2;
- XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % 6],
- dest, clip,
- 0, 0, squareSize, squareSize,
- 0, 0);
- }
-}
-
-/* Animate the movement of a single piece */
-
-static void
-BeginAnimation(anim, piece, startColor, start)
- AnimState *anim;
- ChessSquare piece;
- int startColor;
- XPoint * start;
-{
- Pixmap mask;
-
- /* The old buffer is initialised with the start square (empty) */
- BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);
- anim->prevFrame = *start;
-
- /* The piece will be drawn using its own bitmap as a matte */
- SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
- XSetClipMask(xDisplay, anim->pieceGC, mask);
-}
-
-static void
-AnimationFrame(anim, frame, piece)
- AnimState *anim;
- XPoint *frame;
- ChessSquare piece;
-{
- XRectangle updates[4];
- XRectangle overlap;
- XPoint pt;
- int count, i;
-
- /* Save what we are about to draw into the new buffer */
- XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
- frame->x, frame->y, squareSize, squareSize,
- 0, 0);
-
- /* Erase bits of the previous frame */
- if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {
- /* Where the new frame overlapped the previous,
- the contents in newBuf are wrong. */
- XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
- overlap.x, overlap.y,
- overlap.width, overlap.height,
- pt.x, pt.y);
- /* Repaint the areas in the old that don't overlap new */
- CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);
- for (i = 0; i < count; i++)
- XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
- updates[i].x - anim->prevFrame.x,
- updates[i].y - anim->prevFrame.y,
- updates[i].width, updates[i].height,
- updates[i].x, updates[i].y);
- } else {
- /* Easy when no overlap */
- XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
- 0, 0, squareSize, squareSize,
- anim->prevFrame.x, anim->prevFrame.y);
- }
-
- /* Save this frame for next time round */
- XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
- 0, 0, squareSize, squareSize,
- 0, 0);
- anim->prevFrame = *frame;
-
- /* Draw piece over original screen contents, not current,
- and copy entire rect. Wipes out overlapping piece images. */
- OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);
- XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
- 0, 0, squareSize, squareSize,
- frame->x, frame->y);
-}
-
-static void
-EndAnimation (anim, finish)
- AnimState *anim;
- XPoint *finish;
-{
- XRectangle updates[4];
- XRectangle overlap;
- XPoint pt;
- int count, i;
-
- /* The main code will redraw the final square, so we
- only need to erase the bits that don't overlap. */
- if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {
- CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);
- for (i = 0; i < count; i++)
- XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
- updates[i].x - anim->prevFrame.x,
- updates[i].y - anim->prevFrame.y,
- updates[i].width, updates[i].height,
- updates[i].x, updates[i].y);
- } else {
- XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
- 0, 0, squareSize, squareSize,
- anim->prevFrame.x, anim->prevFrame.y);
- }
-}
-
-static void
-FrameSequence(anim, piece, startColor, start, finish, frames, nFrames)
- AnimState *anim;
- ChessSquare piece; int startColor;
- XPoint * start; XPoint * finish;
- XPoint frames[]; int nFrames;
-{
- int n;
-
- BeginAnimation(anim, piece, startColor, start);
- for (n = 0; n < nFrames; n++) {
- AnimationFrame(anim, &(frames[n]), piece);
- FrameDelay(appData.animSpeed);
- }
- EndAnimation(anim, finish);
-}
-
-/* Main control logic for deciding what to animate and how */
-
-void
-AnimateMove(board, fromX, fromY, toX, toY)
- Board board;
- int fromX;
- int fromY;
- int toX;
- int toY;
-{
- ChessSquare piece;
- int hop;
- XPoint start, finish, mid;
- XPoint frames[kFactor * 2 + 1];
- int nFrames, startColor, endColor;
-
- /* Are we animating? */
- if (!appData.animate || appData.blindfold)
- return;
-
- if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
- piece = board[fromY][fromX];
- if (piece >= EmptySquare) return;
-
-#if DONT_HOP
- hop = FALSE;
-#else
- hop = (piece == WhiteKnight || piece == BlackKnight);
-#endif
-
- if (appData.debugMode) {
- printf("AnimateMove: piece %d %s from %d,%d to %d,%d \n",
- piece, hop ? "hops" : "slides", fromX, fromY, toX, toY);
- }
-
- ScreenSquare(fromX, fromY, &start, &startColor);
- ScreenSquare(toX, toY, &finish, &endColor);
-
- if (hop) {
- /* Knight: make diagonal movement then straight */
- if (abs(toY - fromY) < abs(toX - fromX)) {
- mid.x = start.x + (finish.x - start.x) / 2;
- mid.y = finish.y;
- } else {
- mid.x = finish.x;
- mid.y = start.y + (finish.y - start.y) / 2;
- }
- } else {
- mid.x = start.x + (finish.x - start.x) / 2;
- mid.y = start.y + (finish.y - start.y) / 2;
- }
-
- /* Don't use as many frames for very short moves */
- if (abs(toY - fromY) + abs(toX - fromX) <= 2)
- Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);
- else
- Tween(&start, &mid, &finish, kFactor, frames, &nFrames);
- FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
-
- /* Be sure end square is redrawn */
- damage[toY][toX] = True;
-}
-
-static void
-DragPieceBegin(x, y)
- int x; int y;
-{
- int boardX, boardY, color;
- XPoint corner;
-
- /* Are we animating? */
- if (!appData.animateDragging || appData.blindfold)
- return;
-
- /* Figure out which square we start in and the
- mouse position relative to top left corner. */
- BoardSquare(x, y, &boardX, &boardY);
- player.startBoardX = boardX;
- player.startBoardY = boardY;
- ScreenSquare(boardX, boardY, &corner, &color);
- player.startSquare = corner;
- player.startColor = color;
-#if 0
- /* Start from exactly where the piece is. This can be confusing
- if you start dragging far from the center of the square; most
- or all of the piece can be over a different square from the one
- the mouse pointer is in. */
- player.mouseDelta.x = x - corner.x;
- player.mouseDelta.y = y - corner.y;
-#else
- /* As soon as we start dragging, the piece will jump slightly to
- be centered over the mouse pointer. */
- player.mouseDelta.x = squareSize/2;
- player.mouseDelta.y = squareSize/2;
-#endif
- /* Initialise animation */
- player.dragPiece = PieceForSquare(boardX, boardY);
- /* Sanity check */
- if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {
- player.dragActive = True;
- BeginAnimation(&player, player.dragPiece, color, &corner);
- /* Mark this square as needing to be redrawn. Note that
- we don't remove the piece though, since logically (ie
- as seen by opponent) the move hasn't been made yet. */
- damage[boardY][boardX] = True;
- } else {
- player.dragActive = False;
- }
-}
-
-static void
-DragPieceMove(x, y)
- int x; int y;
-{
- XPoint corner;
-
- /* Are we animating? */
- if (!appData.animateDragging || appData.blindfold)
- return;
-
- /* Sanity check */
- if (! player.dragActive)
- return;
- /* Move piece, maintaining same relative position
- of mouse within square */
- corner.x = x - player.mouseDelta.x;
- corner.y = y - player.mouseDelta.y;
- AnimationFrame(&player, &corner, player.dragPiece);
-#if HIGHDRAG
- if (appData.highlightDragging) {
- int boardX, boardY;
- BoardSquare(x, y, &boardX, &boardY);
- SetHighlights(fromX, fromY, boardX, boardY);
- }
-#endif
-}
-
-static void
-DragPieceEnd(x, y)
- int x; int y;
-{
- int boardX, boardY, color;
- XPoint corner;
-
- /* Are we animating? */
- if (!appData.animateDragging || appData.blindfold)
- return;
-
- /* Sanity check */
- if (! player.dragActive)
- return;
- /* Last frame in sequence is square piece is
- placed on, which may not match mouse exactly. */
- BoardSquare(x, y, &boardX, &boardY);
- ScreenSquare(boardX, boardY, &corner, &color);
- EndAnimation(&player, &corner);
-
- /* Be sure end square is redrawn */
- damage[boardY][boardX] = True;
-
- /* This prevents weird things happening with fast successive
- clicks which on my Sun at least can cause motion events
- without corresponding press/release. */
- player.dragActive = False;
-}
-
-/* Handle expose event while piece being dragged */
-
-static void
-DrawDragPiece ()
-{
- if (!player.dragActive || appData.blindfold)
- return;
-
- /* What we're doing: logically, the move hasn't been made yet,
- so the piece is still in it's original square. But visually
- it's being dragged around the board. So we erase the square
- that the piece is on and draw it at the last known drag point. */
- BlankSquare(player.startSquare.x, player.startSquare.y,
- player.startColor, EmptySquare, xBoardWindow);
- AnimationFrame(&player, &player.prevFrame, player.dragPiece);
- damage[player.startBoardY][player.startBoardX] = TRUE;
-}
-
+/*\r
+ * xboard.c -- X front end for XBoard\r
+ * $Id: xboard.c,v 2.2 2003/11/06 07:22:14 mann Exp $\r
+ *\r
+ * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.\r
+ * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.\r
+ *\r
+ * The following terms apply to Digital Equipment Corporation's copyright\r
+ * interest in XBoard:\r
+ * ------------------------------------------------------------------------\r
+ * All Rights Reserved\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose and without fee is hereby granted,\r
+ * provided that the above copyright notice appear in all copies and that\r
+ * both that copyright notice and this permission notice appear in\r
+ * supporting documentation, and that the name of Digital not be\r
+ * used in advertising or publicity pertaining to distribution of the\r
+ * software without specific, written prior permission.\r
+ *\r
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING\r
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL\r
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR\r
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\r
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\r
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
+ * SOFTWARE.\r
+ * ------------------------------------------------------------------------\r
+ *\r
+ * The following terms apply to the enhanced version of XBoard distributed\r
+ * by the Free Software Foundation:\r
+ * ------------------------------------------------------------------------\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ * ------------------------------------------------------------------------\r
+ *\r
+ * See the file ChangeLog for a revision history.\r
+ */\r
+\r
+#include "config.h"\r
+\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <signal.h>\r
+#include <errno.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <pwd.h>\r
+\r
+#if !OMIT_SOCKETS\r
+# if HAVE_SYS_SOCKET_H\r
+# include <sys/socket.h>\r
+# include <netinet/in.h>\r
+# include <netdb.h>\r
+# else /* not HAVE_SYS_SOCKET_H */\r
+# if HAVE_LAN_SOCKET_H\r
+# include <lan/socket.h>\r
+# include <lan/in.h>\r
+# include <lan/netdb.h>\r
+# else /* not HAVE_LAN_SOCKET_H */\r
+# define OMIT_SOCKETS 1\r
+# endif /* not HAVE_LAN_SOCKET_H */\r
+# endif /* not HAVE_SYS_SOCKET_H */\r
+#endif /* !OMIT_SOCKETS */\r
+\r
+#if STDC_HEADERS\r
+# include <stdlib.h>\r
+# include <string.h>\r
+#else /* not STDC_HEADERS */\r
+extern char *getenv();\r
+# if HAVE_STRING_H\r
+# include <string.h>\r
+# else /* not HAVE_STRING_H */\r
+# include <strings.h>\r
+# endif /* not HAVE_STRING_H */\r
+#endif /* not STDC_HEADERS */\r
+\r
+#if HAVE_SYS_FCNTL_H\r
+# include <sys/fcntl.h>\r
+#else /* not HAVE_SYS_FCNTL_H */\r
+# if HAVE_FCNTL_H\r
+# include <fcntl.h>\r
+# endif /* HAVE_FCNTL_H */\r
+#endif /* not HAVE_SYS_FCNTL_H */\r
+\r
+#if HAVE_SYS_SYSTEMINFO_H\r
+# include <sys/systeminfo.h>\r
+#endif /* HAVE_SYS_SYSTEMINFO_H */\r
+\r
+#if TIME_WITH_SYS_TIME\r
+# include <sys/time.h>\r
+# include <time.h>\r
+#else\r
+# if HAVE_SYS_TIME_H\r
+# include <sys/time.h>\r
+# else\r
+# include <time.h>\r
+# endif\r
+#endif\r
+\r
+#if HAVE_UNISTD_H\r
+# include <unistd.h>\r
+#endif\r
+\r
+#if HAVE_SYS_WAIT_H\r
+# include <sys/wait.h>\r
+#endif\r
+\r
+#if HAVE_DIRENT_H\r
+# include <dirent.h>\r
+# define NAMLEN(dirent) strlen((dirent)->d_name)\r
+# define HAVE_DIR_STRUCT\r
+#else\r
+# define dirent direct\r
+# define NAMLEN(dirent) (dirent)->d_namlen\r
+# if HAVE_SYS_NDIR_H\r
+# include <sys/ndir.h>\r
+# define HAVE_DIR_STRUCT\r
+# endif\r
+# if HAVE_SYS_DIR_H\r
+# include <sys/dir.h>\r
+# define HAVE_DIR_STRUCT\r
+# endif\r
+# if HAVE_NDIR_H\r
+# include <ndir.h>\r
+# define HAVE_DIR_STRUCT\r
+# endif\r
+#endif\r
+\r
+#include <X11/Intrinsic.h>\r
+#include <X11/StringDefs.h>\r
+#include <X11/Shell.h>\r
+#include <X11/cursorfont.h>\r
+#include <X11/Xatom.h>\r
+#if USE_XAW3D\r
+#include <X11/Xaw3d/Dialog.h>\r
+#include <X11/Xaw3d/Form.h>\r
+#include <X11/Xaw3d/List.h>\r
+#include <X11/Xaw3d/Label.h>\r
+#include <X11/Xaw3d/SimpleMenu.h>\r
+#include <X11/Xaw3d/SmeBSB.h>\r
+#include <X11/Xaw3d/SmeLine.h>\r
+#include <X11/Xaw3d/Box.h>\r
+#include <X11/Xaw3d/MenuButton.h>\r
+#include <X11/Xaw3d/Text.h>\r
+#include <X11/Xaw3d/AsciiText.h>\r
+#else\r
+#include <X11/Xaw/Dialog.h>\r
+#include <X11/Xaw/Form.h>\r
+#include <X11/Xaw/List.h>\r
+#include <X11/Xaw/Label.h>\r
+#include <X11/Xaw/SimpleMenu.h>\r
+#include <X11/Xaw/SmeBSB.h>\r
+#include <X11/Xaw/SmeLine.h>\r
+#include <X11/Xaw/Box.h>\r
+#include <X11/Xaw/MenuButton.h>\r
+#include <X11/Xaw/Text.h>\r
+#include <X11/Xaw/AsciiText.h>\r
+#endif\r
+\r
+// [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.\r
+#include "common.h"\r
+\r
+#if HAVE_LIBXPM\r
+#include <X11/xpm.h>\r
+#include "pixmaps/pixmaps.h"\r
+#define IMAGE_EXT "xpm"\r
+#else\r
+#define IMAGE_EXT "xim"\r
+#include "bitmaps/bitmaps.h"\r
+#endif\r
+\r
+#include "bitmaps/icon_white.bm"\r
+#include "bitmaps/icon_black.bm"\r
+#include "bitmaps/checkmark.bm"\r
+\r
+#include "frontend.h"\r
+#include "backend.h"\r
+#include "moves.h"\r
+#include "xboard.h"\r
+#include "childio.h"\r
+#include "xgamelist.h"\r
+#include "xhistory.h"\r
+#include "xedittags.h"\r
+\r
+#ifdef __EMX__\r
+#ifndef HAVE_USLEEP\r
+#define HAVE_USLEEP\r
+#endif\r
+#define usleep(t) _sleep2(((t)+500)/1000)\r
+#endif\r
+\r
+typedef struct {\r
+ String string;\r
+ XtActionProc proc;\r
+} MenuItem;\r
+\r
+typedef struct {\r
+ String name;\r
+ MenuItem *mi;\r
+} Menu;\r
+\r
+int main P((int argc, char **argv));\r
+RETSIGTYPE CmailSigHandler P((int sig));\r
+RETSIGTYPE IntSigHandler P((int sig));\r
+void CreateGCs P((void));\r
+void CreateXIMPieces P((void));\r
+void CreateXPMPieces P((void));\r
+void CreatePieces P((void));\r
+void CreatePieceMenus P((void));\r
+Widget CreateMenuBar P((Menu *mb));\r
+Widget CreateButtonBar P ((MenuItem *mi));\r
+char *FindFont P((char *pattern, int targetPxlSize));\r
+void PieceMenuPopup P((Widget w, XEvent *event,\r
+ String *params, Cardinal *num_params));\r
+static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));\r
+static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));\r
+void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],\r
+ u_int wreq, u_int hreq));\r
+void CreateGrid P((void));\r
+int EventToSquare P((int x, int limit));\r
+void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));\r
+void EventProc P((Widget widget, caddr_t unused, XEvent *event));\r
+void HandleUserMove P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AnimateUserMove P((Widget w, XEvent * event,\r
+ String * params, Cardinal * nParams));\r
+void WhiteClock P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void BlackClock P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void DrawPositionProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void XDrawPosition P((Widget w, /*Boolean*/int repaint, \r
+ Board board));\r
+void CommentPopUp P((char *title, char *label));\r
+void CommentPopDown P((void));\r
+void CommentCallback P((Widget w, XtPointer client_data,\r
+ XtPointer call_data));\r
+void ICSInputBoxPopUp P((void));\r
+void ICSInputBoxPopDown P((void));\r
+void FileNamePopUp P((char *label, char *def,\r
+ FileProc proc, char *openMode));\r
+void FileNamePopDown P((void));\r
+void FileNameCallback P((Widget w, XtPointer client_data,\r
+ XtPointer call_data));\r
+void FileNameAction P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AskQuestionReplyAction P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AskQuestionProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AskQuestionPopDown P((void));\r
+void PromotionPopUp P((void));\r
+void PromotionPopDown P((void));\r
+void PromotionCallback P((Widget w, XtPointer client_data,\r
+ XtPointer call_data));\r
+void EditCommentPopDown P((void));\r
+void EditCommentCallback P((Widget w, XtPointer client_data,\r
+ XtPointer call_data));\r
+void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));\r
+void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void LoadNextGameProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void ReloadGameProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void LoadPositionProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void ReloadPositionProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void CopyPositionProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void PastePositionProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void SavePositionProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void MachineBlackProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void MachineWhiteProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AnalyzeModeProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AnalyzeFileProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void TwoMachinesProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void IcsClientProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void EditPositionProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void EditCommentProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void IcsInputBoxProc P((Widget w, XEvent *event,\r
+ String *prms, Cardinal *nprms));\r
+void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void StopObservingProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void StopExaminingProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void TruncateGameProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void RetractMoveProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void AnimateMovingProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void AutocommProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AutobsProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void FlashMovesProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void GetMoveListProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ShowCoordsProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void ShowThinkingProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void TestLegalityProc P((Widget w, XEvent *event, String *prms,\r
+ Cardinal *nprms));\r
+void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void DisplayMove P((int moveNumber));\r
+void DisplayTitle P((char *title));\r
+void ICSInitScript P((void));\r
+int LoadGamePopUp P((FILE *f, int gameNumber, char *title));\r
+void ErrorPopUp P((char *title, char *text, int modal));\r
+void ErrorPopDown P((void));\r
+static char *ExpandPathName P((char *path));\r
+static void CreateAnimVars P((void));\r
+static void DragPieceBegin P((int x, int y));\r
+static void DragPieceMove P((int x, int y));\r
+static void DragPieceEnd P((int x, int y));\r
+static void DrawDragPiece P((void));\r
+char *ModeToWidgetName P((GameMode mode));\r
+\r
+/*\r
+* XBoard depends on Xt R4 or higher\r
+*/\r
+int xtVersion = XtSpecificationRelease;\r
+\r
+int xScreen;\r
+Display *xDisplay;\r
+Window xBoardWindow;\r
+Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,\r
+ jailSquareColor, highlightSquareColor, premoveHighlightColor;\r
+GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,\r
+ bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,\r
+ wjPieceGC, bjPieceGC, prelineGC;\r
+Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;\r
+Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget, \r
+ whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16], \r
+ commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,\r
+ menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,\r
+ ICSInputShell, fileNameShell, askQuestionShell;\r
+XSegment gridSegments[(BOARD_SIZE + 1) * 2];\r
+XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];\r
+Font clockFontID, coordFontID;\r
+XFontStruct *clockFontStruct, *coordFontStruct;\r
+XtAppContext appContext;\r
+char *layoutName;\r
+char *oldICSInteractionTitle;\r
+\r
+FileProc fileProc;\r
+char *fileOpenMode;\r
+\r
+Position commentX = -1, commentY = -1;\r
+Dimension commentW, commentH;\r
+\r
+int squareSize, smallLayout = 0, tinyLayout = 0,\r
+ fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,\r
+ ICSInputBoxUp = False, askQuestionUp = False,\r
+ filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,\r
+ editUp = False, errorUp = False, errorExitStatus = -1, lineGap;\r
+Pixel timerForegroundPixel, timerBackgroundPixel;\r
+Pixel buttonForegroundPixel, buttonBackgroundPixel;\r
+char *chessDir, *programName, *programVersion,\r
+ *gameCopyFilename, *gamePasteFilename;\r
+\r
+#define SOLID 0\r
+#define OUTLINE 1\r
+Pixmap pieceBitmap[2][(int)BlackPawn];\r
+Pixmap xpmPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */\r
+Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;\r
+int useImages, useImageSqs;\r
+XImage *ximPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */\r
+Pixmap ximMaskPm[(int)BlackPawn]; /* clipmasks, used for XIM pieces */\r
+XImage *ximLightSquare, *ximDarkSquare;\r
+XImage *xim_Cross;\r
+\r
+#define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % (int)BlackPawn]\r
+#define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % (int)BlackPawn]\r
+\r
+#define White(piece) ((int)(piece) < (int)BlackPawn)\r
+\r
+/* Variables for doing smooth animation. This whole thing\r
+ would be much easier if the board was double-buffered,\r
+ but that would require a fairly major rewrite. */\r
+\r
+typedef struct {\r
+ Pixmap saveBuf;\r
+ Pixmap newBuf;\r
+ GC blitGC, pieceGC, outlineGC;\r
+ XPoint startSquare, prevFrame, mouseDelta;\r
+ int startColor;\r
+ int dragPiece;\r
+ Boolean dragActive;\r
+ int startBoardX, startBoardY;\r
+ } AnimState;\r
+\r
+/* There can be two pieces being animated at once: a player\r
+ can begin dragging a piece before the remote opponent has moved. */\r
+\r
+static AnimState game, player;\r
+\r
+/* Bitmaps for use as masks when drawing XPM pieces.\r
+ Need one for each black and white piece. */\r
+static Pixmap xpmMask[BlackKing + 1];\r
+\r
+/* This magic number is the number of intermediate frames used\r
+ in each half of the animation. For short moves it's reduced\r
+ by 1. The total number of frames will be factor * 2 + 1. */\r
+#define kFactor 4\r
+\r
+SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;\r
+\r
+MenuItem fileMenu[] = {\r
+ {"Reset Game", ResetProc},\r
+ {"----", NothingProc},\r
+ {"Load Game", LoadGameProc},\r
+ {"Load Next Game", LoadNextGameProc},\r
+ {"Load Previous Game", LoadPrevGameProc},\r
+ {"Reload Same Game", ReloadGameProc},\r
+ {"Save Game", SaveGameProc},\r
+ {"----", NothingProc},\r
+ {"Copy Game", CopyGameProc},\r
+ {"Paste Game", PasteGameProc},\r
+ {"----", NothingProc},\r
+ {"Load Position", LoadPositionProc},\r
+ {"Load Next Position", LoadNextPositionProc},\r
+ {"Load Previous Position", LoadPrevPositionProc},\r
+ {"Reload Same Position", ReloadPositionProc},\r
+ {"Save Position", SavePositionProc},\r
+ {"----", NothingProc},\r
+ {"Copy Position", CopyPositionProc},\r
+ {"Paste Position", PastePositionProc},\r
+ {"----", NothingProc},\r
+ {"Mail Move", MailMoveProc},\r
+ {"Reload CMail Message", ReloadCmailMsgProc},\r
+ {"----", NothingProc},\r
+ {"Exit", QuitProc},\r
+ {NULL, NULL}\r
+};\r
+\r
+MenuItem modeMenu[] = {\r
+ {"Machine White", MachineWhiteProc},\r
+ {"Machine Black", MachineBlackProc},\r
+ {"Two Machines", TwoMachinesProc},\r
+ {"Analysis Mode", AnalyzeModeProc},\r
+ {"Analyze File", AnalyzeFileProc },\r
+ {"ICS Client", IcsClientProc},\r
+ {"Edit Game", EditGameProc},\r
+ {"Edit Position", EditPositionProc},\r
+ {"Training", TrainingProc},\r
+ {"----", NothingProc},\r
+ {"Show Game List", ShowGameListProc},\r
+ {"Show Move List", HistoryShowProc},\r
+ {"Edit Tags", EditTagsProc},\r
+ {"Edit Comment", EditCommentProc},\r
+ {"ICS Input Box", IcsInputBoxProc},\r
+ {"Pause", PauseProc},\r
+ {NULL, NULL}\r
+};\r
+\r
+MenuItem actionMenu[] = {\r
+ {"Accept", AcceptProc},\r
+ {"Decline", DeclineProc},\r
+ {"Rematch", RematchProc},\r
+ {"----", NothingProc}, \r
+ {"Call Flag", CallFlagProc},\r
+ {"Draw", DrawProc},\r
+ {"Adjourn", AdjournProc},\r
+ {"Abort", AbortProc},\r
+ {"Resign", ResignProc},\r
+ {"----", NothingProc}, \r
+ {"Stop Observing", StopObservingProc},\r
+ {"Stop Examining", StopExaminingProc},\r
+ {NULL, NULL}\r
+};\r
+\r
+MenuItem stepMenu[] = {\r
+ {"Backward", BackwardProc},\r
+ {"Forward", ForwardProc},\r
+ {"Back to Start", ToStartProc},\r
+ {"Forward to End", ToEndProc},\r
+ {"Revert", RevertProc},\r
+ {"Truncate Game", TruncateGameProc},\r
+ {"----", NothingProc}, \r
+ {"Move Now", MoveNowProc},\r
+ {"Retract Move", RetractMoveProc},\r
+ {NULL, NULL}\r
+}; \r
+\r
+MenuItem optionsMenu[] = {\r
+ {"Always Queen", AlwaysQueenProc},\r
+ {"Animate Dragging", AnimateDraggingProc},\r
+ {"Animate Moving", AnimateMovingProc},\r
+ {"Auto Comment", AutocommProc},\r
+ {"Auto Flag", AutoflagProc},\r
+ {"Auto Flip View", AutoflipProc},\r
+ {"Auto Observe", AutobsProc},\r
+ {"Auto Raise Board", AutoraiseProc},\r
+ {"Auto Save", AutosaveProc},\r
+ {"Blindfold", BlindfoldProc},\r
+ {"Flash Moves", FlashMovesProc},\r
+ {"Flip View", FlipViewProc},\r
+ {"Get Move List", GetMoveListProc},\r
+#if HIGHDRAG\r
+ {"Highlight Dragging", HighlightDraggingProc},\r
+#endif\r
+ {"Highlight Last Move", HighlightLastMoveProc},\r
+ {"Move Sound", MoveSoundProc},\r
+ {"ICS Alarm", IcsAlarmProc},\r
+ {"Old Save Style", OldSaveStyleProc},\r
+ {"Periodic Updates", PeriodicUpdatesProc}, \r
+ {"Ponder Next Move", PonderNextMoveProc},\r
+ {"Popup Exit Message", PopupExitMessageProc}, \r
+ {"Popup Move Errors", PopupMoveErrorsProc}, \r
+ {"Premove", PremoveProc},\r
+ {"Quiet Play", QuietPlayProc},\r
+ {"Show Coords", ShowCoordsProc},\r
+ {"Show Thinking", ShowThinkingProc},\r
+ {"Test Legality", TestLegalityProc},\r
+ {NULL, NULL}\r
+};\r
+\r
+MenuItem helpMenu[] = {\r
+ {"Info XBoard", InfoProc},\r
+ {"Man XBoard", ManProc},\r
+ {"----", NothingProc},\r
+ {"Hint", HintProc},\r
+ {"Book", BookProc},\r
+ {"----", NothingProc},\r
+ {"About XBoard", AboutProc},\r
+ {NULL, NULL}\r
+};\r
+\r
+Menu menuBar[] = {\r
+ {"File", fileMenu},\r
+ {"Mode", modeMenu},\r
+ {"Action", actionMenu},\r
+ {"Step", stepMenu},\r
+ {"Options", optionsMenu},\r
+ {"Help", helpMenu},\r
+ {NULL, NULL}\r
+};\r
+\r
+#define PAUSE_BUTTON "P"\r
+MenuItem buttonBar[] = {\r
+ {"<<", ToStartProc},\r
+ {"<", BackwardProc},\r
+ {PAUSE_BUTTON, PauseProc},\r
+ {">", ForwardProc},\r
+ {">>", ToEndProc},\r
+ {NULL, NULL}\r
+};\r
+\r
+#define PIECE_MENU_SIZE 11\r
+String pieceMenuStrings[2][PIECE_MENU_SIZE] = {\r
+ { "White", "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",\r
+ "----", "Empty square", "Clear board" },\r
+ { "Black", "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",\r
+ "----", "Empty square", "Clear board" },\r
+ };\r
+/* must be in same order as PieceMenuStrings! */\r
+ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {\r
+ { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,\r
+ WhiteRook, WhiteQueen, WhiteKing,\r
+ (ChessSquare) 0, EmptySquare, ClearBoard },\r
+ { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,\r
+ BlackRook, BlackQueen, BlackKing,\r
+ (ChessSquare) 0, EmptySquare, ClearBoard },\r
+};\r
+\r
+#define DROP_MENU_SIZE 6\r
+String dropMenuStrings[DROP_MENU_SIZE] = {\r
+ "----", "Pawn", "Knight", "Bishop", "Rook", "Queen"\r
+ };\r
+/* must be in same order as PieceMenuStrings! */\r
+ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {\r
+ (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,\r
+ WhiteRook, WhiteQueen\r
+};\r
+\r
+typedef struct {\r
+ char piece;\r
+ char* widget;\r
+} DropMenuEnables;\r
+\r
+DropMenuEnables dmEnables[] = {\r
+ { 'P', "Pawn" },\r
+ { 'N', "Knight" },\r
+ { 'B', "Bishop" },\r
+ { 'R', "Rook" },\r
+ { 'Q', "Queen" }\r
+};\r
+\r
+Arg shellArgs[] = {\r
+ { XtNwidth, 0 },\r
+ { XtNheight, 0 },\r
+ { XtNminWidth, 0 },\r
+ { XtNminHeight, 0 },\r
+ { XtNmaxWidth, 0 },\r
+ { XtNmaxHeight, 0 }\r
+};\r
+\r
+Arg layoutArgs[] = {\r
+ { XtNborderWidth, 0 },\r
+ { XtNdefaultDistance, 0 },\r
+};\r
+\r
+Arg formArgs[] = {\r
+ { XtNborderWidth, 0 },\r
+ { XtNresizable, (XtArgVal) True },\r
+};\r
+\r
+Arg boardArgs[] = {\r
+ { XtNborderWidth, 0 },\r
+ { XtNwidth, 0 },\r
+ { XtNheight, 0 }\r
+};\r
+\r
+Arg titleArgs[] = {\r
+ { XtNjustify, (XtArgVal) XtJustifyRight },\r
+ { XtNlabel, (XtArgVal) "..." },\r
+ { XtNresizable, (XtArgVal) True },\r
+ { XtNresize, (XtArgVal) False }\r
+};\r
+\r
+Arg messageArgs[] = {\r
+ { XtNjustify, (XtArgVal) XtJustifyLeft },\r
+ { XtNlabel, (XtArgVal) "..." },\r
+ { XtNresizable, (XtArgVal) True },\r
+ { XtNresize, (XtArgVal) False }\r
+};\r
+\r
+Arg timerArgs[] = {\r
+ { XtNborderWidth, 0 },\r
+ { XtNjustify, (XtArgVal) XtJustifyLeft }\r
+};\r
+\r
+XtResource clientResources[] = {\r
+ { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, whitePieceColor), XtRString,\r
+ WHITE_PIECE_COLOR },\r
+ { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, blackPieceColor), XtRString,\r
+ BLACK_PIECE_COLOR },\r
+ { "lightSquareColor", "lightSquareColor", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, lightSquareColor),\r
+ XtRString, LIGHT_SQUARE_COLOR }, \r
+ { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, darkSquareColor), XtRString,\r
+ DARK_SQUARE_COLOR },\r
+ { "highlightSquareColor", "highlightSquareColor", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),\r
+ XtRString, HIGHLIGHT_SQUARE_COLOR },\r
+ { "premoveHighlightColor", "premoveHighlightColor", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),\r
+ XtRString, PREMOVE_HIGHLIGHT_COLOR },\r
+ { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, movesPerSession), XtRImmediate,\r
+ (XtPointer) MOVES_PER_SESSION },\r
+ { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, timeIncrement), XtRImmediate,\r
+ (XtPointer) TIME_INCREMENT },\r
+ { "initString", "initString", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },\r
+ { "secondInitString", "secondInitString", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },\r
+ { "firstComputerString", "firstComputerString", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,\r
+ COMPUTER_STRING },\r
+ { "secondComputerString", "secondComputerString", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,\r
+ COMPUTER_STRING },\r
+ { "firstChessProgram", "firstChessProgram", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, firstChessProgram),\r
+ XtRString, FIRST_CHESS_PROGRAM },\r
+ { "secondChessProgram", "secondChessProgram", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, secondChessProgram),\r
+ XtRString, SECOND_CHESS_PROGRAM },\r
+ { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "noChessProgram", "noChessProgram", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "firstHost", "firstHost", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },\r
+ { "secondHost", "secondHost", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },\r
+ { "firstDirectory", "firstDirectory", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, firstDirectory), XtRString, FIRST_DIRECTORY },\r
+ { "secondDirectory", "secondDirectory", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, secondDirectory), XtRString, SECOND_DIRECTORY },\r
+ { "bitmapDirectory", "bitmapDirectory", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),\r
+ XtRString, "" },\r
+ { "remoteShell", "remoteShell", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },\r
+ { "remoteUser", "remoteUser", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, remoteUser), XtRString, "" },\r
+ { "timeDelay", "timeDelay", XtRFloat, sizeof(float),\r
+ XtOffset(AppDataPtr, timeDelay), XtRString,\r
+ (XtPointer) TIME_DELAY_QUOTE },\r
+ { "timeControl", "timeControl", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, timeControl), XtRString,\r
+ (XtPointer) TIME_CONTROL },\r
+ { "internetChessServerMode", "internetChessServerMode",\r
+ XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, icsActive), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "internetChessServerHost", "internetChessServerHost",\r
+ XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, icsHost),\r
+ XtRString, (XtPointer) ICS_HOST },\r
+ { "internetChessServerPort", "internetChessServerPort",\r
+ XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, icsPort), XtRString,\r
+ (XtPointer) ICS_PORT },\r
+ { "internetChessServerCommPort", "internetChessServerCommPort",\r
+ XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, icsCommPort), XtRString,\r
+ ICS_COMM_PORT },\r
+ { "internetChessServerLogonScript", "internetChessServerLogonScript",\r
+ XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, icsLogon), XtRString,\r
+ ICS_LOGON },\r
+ { "internetChessServerHelper", "internetChessServerHelper",\r
+ XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, icsHelper), XtRString, "" },\r
+ { "internetChessServerInputBox", "internetChessServerInputBox",\r
+ XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, icsInputBox), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "icsAlarm", "icsAlarm",\r
+ XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, icsAlarm), XtRImmediate,\r
+ (XtPointer) True },\r
+ { "icsAlarmTime", "icsAlarmTime",\r
+ XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,\r
+ (XtPointer) 5000 },\r
+ { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, useTelnet), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "telnetProgram", "telnetProgram", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },\r
+ { "gateway", "gateway", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, gateway), XtRString, "" },\r
+ { "loadGameFile", "loadGameFile", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, loadGameFile), XtRString, "" },\r
+ { "loadGameIndex", "loadGameIndex",\r
+ XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,\r
+ (XtPointer) 0 },\r
+ { "saveGameFile", "saveGameFile", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, saveGameFile), XtRString, "" },\r
+ { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "autoSaveGames", "autoSaveGames", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "blindfold", "blindfold", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, blindfold),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "loadPositionFile", "loadPositionFile", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, loadPositionFile),\r
+ XtRString, "" },\r
+ { "loadPositionIndex", "loadPositionIndex",\r
+ XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,\r
+ (XtPointer) 1 },\r
+ { "savePositionFile", "savePositionFile", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, savePositionFile),\r
+ XtRString, "" },\r
+ { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },\r
+ { "matchGames", "matchGames", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, matchGames), XtRImmediate,\r
+ (XtPointer) 0 },\r
+ { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, monoMode), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, debugMode), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, clockMode), XtRImmediate,\r
+ (XtPointer) True },\r
+ { "boardSize", "boardSize", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, boardSize), XtRString, "" },\r
+ { "searchTime", "searchTime", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, searchTime), XtRString,\r
+ (XtPointer) "" },\r
+ { "searchDepth", "searchDepth", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, searchDepth), XtRImmediate, \r
+ (XtPointer) 0 },\r
+ { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, showCoords), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "showJail", "showJail", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, showJail), XtRImmediate,\r
+ (XtPointer) 0 },\r
+ { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, showThinking), XtRImmediate,\r
+ (XtPointer) False },\r
+ { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,\r
+ (XtPointer) True },\r
+ { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,\r
+ (XtPointer) True },\r
+ { "clockFont", "clockFont", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },\r
+ { "coordFont", "coordFont", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },\r
+ { "font", "font", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },\r
+ { "ringBellAfterMoves", "ringBellAfterMoves",\r
+ XtRBoolean, sizeof(Boolean),\r
+ XtOffset(AppDataPtr, ringBellAfterMoves),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "autoCallFlag", "autoCallFlag", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "autoFlipView", "autoFlipView", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "autoObserve", "autoObserve", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "autoComment", "autoComment", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoComment),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "getMoveList", "getMoveList", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),\r
+ XtRImmediate, (XtPointer) True },\r
+#if HIGHDRAG\r
+ { "highlightDragging", "highlightDragging", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),\r
+ XtRImmediate, (XtPointer) False },\r
+#endif\r
+ { "highlightLastMove", "highlightLastMove", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "premove", "premove", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, premove),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "testLegality", "testLegality", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, testLegality),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "flipView", "flipView", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, flipView),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "cmail", "cmailGameName", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, cmailGameName), XtRString, "" },\r
+ { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "oldSaveStyle", "oldSaveStyle", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "quietPlay", "quietPlay", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "titleInWindow", "titleInWindow", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "localLineEditing", "localLineEditing", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),\r
+ XtRImmediate, (XtPointer) True }, /* not implemented, must be True */\r
+#ifdef ZIPPY\r
+ { "zippyTalk", "zippyTalk", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),\r
+ XtRImmediate, (XtPointer) ZIPPY_TALK },\r
+ { "zippyPlay", "zippyPlay", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),\r
+ XtRImmediate, (XtPointer) ZIPPY_PLAY },\r
+ { "zippyLines", "zippyLines", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },\r
+ { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },\r
+ { "zippyPassword", "zippyPassword", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },\r
+ { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },\r
+ { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyWrongPassword), XtRString,\r
+ ZIPPY_WRONG_PASSWORD },\r
+ { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },\r
+ { "zippyUseI", "zippyUseI", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),\r
+ XtRImmediate, (XtPointer) ZIPPY_USE_I },\r
+ { "zippyBughouse", "zippyBughouse", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, zippyBughouse),\r
+ XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },\r
+ { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),\r
+ XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },\r
+ { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },\r
+ { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },\r
+ { "zippyAdjourn", "zippyAdjourn", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),\r
+ XtRImmediate, (XtPointer) ZIPPY_ADJOURN },\r
+ { "zippyAbort", "zippyAbort", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),\r
+ XtRImmediate, (XtPointer) ZIPPY_ABORT },\r
+ { "zippyVariants", "zippyVariants", XtRString, sizeof(String),\r
+ XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },\r
+ { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,\r
+ (XtPointer) ZIPPY_MAX_GAMES },\r
+ { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,\r
+ (XtPointer) ZIPPY_REPLAY_TIMEOUT },\r
+#endif\r
+ { "flashCount", "flashCount", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, flashCount), XtRImmediate,\r
+ (XtPointer) FLASH_COUNT },\r
+ { "flashRate", "flashRate", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, flashRate), XtRImmediate,\r
+ (XtPointer) FLASH_RATE },\r
+ { "pixmapDirectory", "pixmapDirectory", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),\r
+ XtRString, "" },\r
+ { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),\r
+ XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,\r
+ (XtPointer) MS_LOGIN_DELAY },\r
+ { "colorizeMessages", "colorizeMessages", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, colorize),\r
+ XtRImmediate, (XtPointer) False }, \r
+ { "colorShout", "colorShout", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorShout),\r
+ XtRString, COLOR_SHOUT },\r
+ { "colorSShout", "colorSShout", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorSShout),\r
+ XtRString, COLOR_SSHOUT },\r
+ { "colorChannel1", "colorChannel1", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorChannel1),\r
+ XtRString, COLOR_CHANNEL1 },\r
+ { "colorChannel", "colorChannel", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorChannel),\r
+ XtRString, COLOR_CHANNEL },\r
+ { "colorKibitz", "colorKibitz", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorKibitz),\r
+ XtRString, COLOR_KIBITZ },\r
+ { "colorTell", "colorTell", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorTell),\r
+ XtRString, COLOR_TELL },\r
+ { "colorChallenge", "colorChallenge", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorChallenge),\r
+ XtRString, COLOR_CHALLENGE },\r
+ { "colorRequest", "colorRequest", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorRequest),\r
+ XtRString, COLOR_REQUEST },\r
+ { "colorSeek", "colorSeek", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorSeek),\r
+ XtRString, COLOR_SEEK },\r
+ { "colorNormal", "colorNormal", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, colorNormal),\r
+ XtRString, COLOR_NORMAL }, \r
+ { "soundProgram", "soundProgram", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundProgram),\r
+ XtRString, "play" },\r
+ { "soundShout", "soundShout", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundShout),\r
+ XtRString, "" },\r
+ { "soundSShout", "soundSShout", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundSShout),\r
+ XtRString, "" },\r
+ { "soundChannel1", "soundChannel1", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundChannel1),\r
+ XtRString, "" },\r
+ { "soundChannel", "soundChannel", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundChannel),\r
+ XtRString, "" },\r
+ { "soundKibitz", "soundKibitz", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundKibitz),\r
+ XtRString, "" },\r
+ { "soundTell", "soundTell", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundTell),\r
+ XtRString, "" },\r
+ { "soundChallenge", "soundChallenge", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundChallenge),\r
+ XtRString, "" },\r
+ { "soundRequest", "soundRequest", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundRequest),\r
+ XtRString, "" },\r
+ { "soundSeek", "soundSeek", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundSeek),\r
+ XtRString, "" },\r
+ { "soundMove", "soundMove", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundMove),\r
+ XtRString, "$" },\r
+ { "soundIcsWin", "soundIcsWin", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundIcsWin),\r
+ XtRString, "" },\r
+ { "soundIcsLoss", "soundIcsLoss", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),\r
+ XtRString, "" },\r
+ { "soundIcsDraw", "soundIcsDraw", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),\r
+ XtRString, "" },\r
+ { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),\r
+ XtRString, "" },\r
+ { "soundIcsAlarm", "soundIcsAlarm", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),\r
+ XtRString, "$" },\r
+ { "reuseFirst", "reuseFirst", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "reuseSecond", "reuseSecond", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "animateDragging", "animateDragging", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "animateMoving", "animateMoving", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, animate),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "animateSpeed", "animateSpeed", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, animSpeed),\r
+ XtRImmediate, (XtPointer)10 },\r
+ { "popupExitMessage", "popupExitMessage", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "popupMoveErrors", "popupMoveErrors", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "fontSizeTolerance", "fontSizeTolerance", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),\r
+ XtRImmediate, (XtPointer)4 },\r
+ { "initialMode", "initialMode", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, initialMode),\r
+ XtRImmediate, (XtPointer) "" },\r
+ { "variant", "variant", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, variant),\r
+ XtRImmediate, (XtPointer) "normal" },\r
+ { "firstProtocolVersion", "firstProtocolVersion", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),\r
+ XtRImmediate, (XtPointer)PROTOVER },\r
+ { "secondProtocolVersion", "secondProtocolVersion", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),\r
+ XtRImmediate, (XtPointer)PROTOVER },\r
+ { "showButtonBar", "showButtonBar", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),\r
+ XtRImmediate, (XtPointer) True },\r
+ { "firstScoreAbs", "firstScoreAbs", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "secondScoreAbs", "secondScoreAbs", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),\r
+ XtRImmediate, (XtPointer) False },\r
+ { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),\r
+ XtRImmediate, (XtPointer) 0},\r
+ { "pgnEventHeader", "pgnEventHeader", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),\r
+ XtRImmediate, (XtPointer) "Computer Chess Game" }, \r
+ { "defaultFrcPosition", "defaultFrcPosition", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),\r
+ XtRImmediate, (XtPointer) -1 }, \r
+\r
+ // [HGM] 4.3.xx options\r
+ { "boardWidth", "boardWidth", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, NrFiles),\r
+ XtRImmediate, (XtPointer) -1},\r
+ { "boardHeight", "boardHeight", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, NrRanks),\r
+ XtRImmediate, (XtPointer) -1},\r
+ { "matchPause", "matchPause", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, matchPause),\r
+ XtRImmediate, (XtPointer) 10000},\r
+ { "holdingsSize", "holdingsSize", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, holdingsSize),\r
+ XtRImmediate, (XtPointer) -1},\r
+ { "flipBlack", "flipBlack", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "allWhite", "allWhite", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, allWhite),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "pieceToCharTable", "pieceToCharTable", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),\r
+ XtRImmediate, (XtPointer) 0},\r
+ { "alphaRank", "alphaRank", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "testClaims", "testClaims", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, testClaims),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "checkMates", "checkMates", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, checkMates),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "materialDraws", "materialDraws", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "trivialDraws", "trivialDraws", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "ruleMoves", "ruleMoves", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, ruleMoves),\r
+ XtRImmediate, (XtPointer) 51},\r
+ { "repeatsToDraw", "repeatsToDraw", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, drawRepeats),\r
+ XtRImmediate, (XtPointer) 6},\r
+ { "engineDebugOutput", "engineDebugOutput", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, engineComments),\r
+ XtRImmediate, (XtPointer) 1},\r
+ { "userName", "userName", XtRString,\r
+ sizeof(int), XtOffset(AppDataPtr, userName),\r
+ XtRImmediate, (XtPointer) 0},\r
+ { "autoKibitz", "autoKibitz", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),\r
+ XtRImmediate, (XtPointer) False},\r
+ { "firstTimeOdds", "firstTimeOdds", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),\r
+ XtRImmediate, (XtPointer) 1},\r
+ { "secondTimeOdds", "secondTimeOdds", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),\r
+ XtRImmediate, (XtPointer) 1},\r
+ { "timeOddsMode", "timeOddsMode", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, timeOddsMode),\r
+ XtRImmediate, (XtPointer) 0},\r
+ { "firstAccumulateTC", "firstAccumulateTC", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),\r
+ XtRImmediate, (XtPointer) 1},\r
+ { "secondAccumulateTC", "secondAccumulateTC", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),\r
+ XtRImmediate, (XtPointer) 1},\r
+ { "firstNPS", "firstNPS", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, firstNPS),\r
+ XtRImmediate, (XtPointer) -1},\r
+ { "secondNPS", "secondNPS", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, secondNPS),\r
+ XtRImmediate, (XtPointer) -1},\r
+ { "serverMoves", "serverMoves", XtRString,\r
+ sizeof(String), XtOffset(AppDataPtr, serverMovesName),\r
+ XtRImmediate, (XtPointer) 0},\r
+ { "serverPause", "serverPause", XtRInt,\r
+ sizeof(int), XtOffset(AppDataPtr, serverPause),\r
+ XtRImmediate, (XtPointer) 0},\r
+ { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,\r
+ sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),\r
+ XtRImmediate, (XtPointer) False},\r
+};\r
+\r
+XrmOptionDescRec shellOptions[] = {\r
+ { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },\r
+ { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },\r
+ { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },\r
+ { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },\r
+ { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },\r
+ { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},\r
+ { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },\r
+ { "-mps", "movesPerSession", XrmoptionSepArg, NULL },\r
+ { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },\r
+ { "-inc", "timeIncrement", XrmoptionSepArg, NULL },\r
+ { "-initString", "initString", XrmoptionSepArg, NULL },\r
+ { "-firstInitString", "initString", XrmoptionSepArg, NULL },\r
+ { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },\r
+ { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },\r
+ { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },\r
+ { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },\r
+ { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },\r
+ { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },\r
+ { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },\r
+ { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },\r
+ { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },\r
+ { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },\r
+ { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },\r
+ { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },\r
+ { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },\r
+ { "-firstHost", "firstHost", XrmoptionSepArg, NULL },\r
+ { "-fh", "firstHost", XrmoptionSepArg, NULL },\r
+ { "-secondHost", "secondHost", XrmoptionSepArg, NULL },\r
+ { "-sh", "secondHost", XrmoptionSepArg, NULL },\r
+ { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },\r
+ { "-fd", "firstDirectory", XrmoptionSepArg, NULL },\r
+ { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },\r
+ { "-sd", "secondDirectory", XrmoptionSepArg, NULL },\r
+ { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },\r
+ { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },\r
+ { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },\r
+ { "-rsh", "remoteShell", XrmoptionSepArg, NULL },\r
+ { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },\r
+ { "-ruser", "remoteUser", XrmoptionSepArg, NULL },\r
+ { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },\r
+ { "-td", "timeDelay", XrmoptionSepArg, NULL },\r
+ { "-timeControl", "timeControl", XrmoptionSepArg, NULL },\r
+ { "-tc", "timeControl", XrmoptionSepArg, NULL },\r
+ { "-internetChessServerMode", "internetChessServerMode",\r
+ XrmoptionSepArg, NULL },\r
+ { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },\r
+ { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },\r
+ { "-internetChessServerHost", "internetChessServerHost",\r
+ XrmoptionSepArg, NULL },\r
+ { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },\r
+ { "-internetChessServerPort", "internetChessServerPort",\r
+ XrmoptionSepArg, NULL },\r
+ { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },\r
+ { "-internetChessServerCommPort", "internetChessServerCommPort",\r
+ XrmoptionSepArg, NULL },\r
+ { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },\r
+ { "-internetChessServerLogonScript", "internetChessServerLogonScript",\r
+ XrmoptionSepArg, NULL },\r
+ { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },\r
+ { "-internetChessServerHelper", "internetChessServerHelper",\r
+ XrmoptionSepArg, NULL },\r
+ { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },\r
+ { "-internetChessServerInputBox", "internetChessServerInputBox",\r
+ XrmoptionSepArg, NULL },\r
+ { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },\r
+ { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },\r
+ { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },\r
+ { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },\r
+ { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },\r
+ { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },\r
+ { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },\r
+ { "-telnet", "useTelnet", XrmoptionNoArg, "True" },\r
+ { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },\r
+ { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },\r
+ { "-gateway", "gateway", XrmoptionSepArg, NULL },\r
+ { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },\r
+ { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },\r
+ { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },\r
+ { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },\r
+ { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },\r
+ { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },\r
+ { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },\r
+ { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },\r
+ { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },\r
+ { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },\r
+ { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },\r
+ { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },\r
+ { "-blindfold", "blindfold", XrmoptionSepArg, NULL },\r
+ { "-blind", "blindfold", XrmoptionNoArg, "True" },\r
+ { "-xblind", "blindfold", XrmoptionNoArg, "False" },\r
+ { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },\r
+ { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },\r
+ { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },\r
+ { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },\r
+ { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },\r
+ { "-spf", "savePositionFile", XrmoptionSepArg, NULL },\r
+ { "-matchMode", "matchMode", XrmoptionSepArg, NULL },\r
+ { "-mm", "matchMode", XrmoptionNoArg, "True" },\r
+ { "-xmm", "matchMode", XrmoptionNoArg, "False" },\r
+ { "-matchGames", "matchGames", XrmoptionSepArg, NULL },\r
+ { "-mg", "matchGames", XrmoptionSepArg, NULL },\r
+ { "-monoMode", "monoMode", XrmoptionSepArg, NULL },\r
+ { "-mono", "monoMode", XrmoptionNoArg, "True" },\r
+ { "-xmono", "monoMode", XrmoptionNoArg, "False" },\r
+ { "-debugMode", "debugMode", XrmoptionSepArg, NULL },\r
+ { "-debug", "debugMode", XrmoptionNoArg, "True" },\r
+ { "-xdebug", "debugMode", XrmoptionNoArg, "False" },\r
+ { "-clockMode", "clockMode", XrmoptionSepArg, NULL },\r
+ { "-clock", "clockMode", XrmoptionNoArg, "True" },\r
+ { "-xclock", "clockMode", XrmoptionNoArg, "False" },\r
+ { "-boardSize", "boardSize", XrmoptionSepArg, NULL },\r
+ { "-size", "boardSize", XrmoptionSepArg, NULL },\r
+ { "-searchTime", "searchTime", XrmoptionSepArg, NULL },\r
+ { "-st", "searchTime", XrmoptionSepArg, NULL },\r
+ { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },\r
+ { "-depth", "searchDepth", XrmoptionSepArg, NULL },\r
+ { "-showCoords", "showCoords", XrmoptionSepArg, NULL },\r
+ { "-coords", "showCoords", XrmoptionNoArg, "True" },\r
+ { "-xcoords", "showCoords", XrmoptionNoArg, "False" },\r
+#if JAIL\r
+ { "-showJail", "showJail", XrmoptionSepArg, NULL },\r
+ { "-jail", "showJail", XrmoptionNoArg, "1" },\r
+ { "-sidejail", "showJail", XrmoptionNoArg, "2" },\r
+ { "-xjail", "showJail", XrmoptionNoArg, "0" },\r
+#endif\r
+ { "-showThinking", "showThinking", XrmoptionSepArg, NULL },\r
+ { "-thinking", "showThinking", XrmoptionNoArg, "True" },\r
+ { "-xthinking", "showThinking", XrmoptionNoArg, "False" },\r
+ { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },\r
+ { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },\r
+ { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },\r
+ { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },\r
+ { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },\r
+ { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },\r
+ { "-clockFont", "clockFont", XrmoptionSepArg, NULL },\r
+ { "-coordFont", "coordFont", XrmoptionSepArg, NULL },\r
+ { "-font", "font", XrmoptionSepArg, NULL },\r
+ { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },\r
+ { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },\r
+ { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },\r
+ { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },\r
+ { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },\r
+ { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },\r
+ { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },\r
+ { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },\r
+ { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },\r
+ { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },\r
+ { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },\r
+ { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },\r
+ { "-autobs", "autoObserve", XrmoptionNoArg, "True" },\r
+ { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },\r
+ { "-autoComment", "autoComment", XrmoptionSepArg, NULL },\r
+ { "-autocomm", "autoComment", XrmoptionNoArg, "True" },\r
+ { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },\r
+ { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },\r
+ { "-moves", "getMoveList", XrmoptionNoArg, "True" },\r
+ { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },\r
+#if HIGHDRAG\r
+ { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },\r
+ { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },\r
+ { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },\r
+#endif\r
+ { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },\r
+ { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },\r
+ { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },\r
+ { "-premove", "premove", XrmoptionSepArg, NULL },\r
+ { "-pre", "premove", XrmoptionNoArg, "True" },\r
+ { "-xpre", "premove", XrmoptionNoArg, "False" },\r
+ { "-testLegality", "testLegality", XrmoptionSepArg, NULL },\r
+ { "-legal", "testLegality", XrmoptionNoArg, "True" },\r
+ { "-xlegal", "testLegality", XrmoptionNoArg, "False" },\r
+ { "-flipView", "flipView", XrmoptionSepArg, NULL },\r
+ { "-flip", "flipView", XrmoptionNoArg, "True" },\r
+ { "-xflip", "flipView", XrmoptionNoArg, "False" },\r
+ { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },\r
+ { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",\r
+ XrmoptionSepArg, NULL },\r
+ { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },\r
+ { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },\r
+ { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },\r
+ { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },\r
+ { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },\r
+ { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },\r
+ { "-quiet", "quietPlay", XrmoptionNoArg, "True" },\r
+ { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },\r
+ { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },\r
+ { "-title", "titleInWindow", XrmoptionNoArg, "True" },\r
+ { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },\r
+#ifdef ZIPPY\r
+ { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },\r
+ { "-zt", "zippyTalk", XrmoptionNoArg, "True" },\r
+ { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },\r
+ { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },\r
+ { "-zp", "zippyPlay", XrmoptionNoArg, "True" },\r
+ { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },\r
+ { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },\r
+ { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },\r
+ { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },\r
+ { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },\r
+ { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },\r
+ { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },\r
+ { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },\r
+ { "-zui", "zippyUseI", XrmoptionNoArg, "True" },\r
+ { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },\r
+ { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },\r
+ { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },\r
+ { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },\r
+ { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },\r
+ { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },\r
+ { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },\r
+ { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },\r
+ { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },\r
+ { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },\r
+ { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },\r
+ { "-zab", "zippyAbort", XrmoptionNoArg, "True" },\r
+ { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },\r
+ { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },\r
+ { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },\r
+ { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },\r
+#endif\r
+ { "-flashCount", "flashCount", XrmoptionSepArg, NULL },\r
+ { "-flash", "flashCount", XrmoptionNoArg, "3" },\r
+ { "-xflash", "flashCount", XrmoptionNoArg, "0" },\r
+ { "-flashRate", "flashRate", XrmoptionSepArg, NULL },\r
+ { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },\r
+ { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },\r
+ { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },\r
+ { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },\r
+ { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },\r
+ { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },\r
+ { "-colorShout", "colorShout", XrmoptionSepArg, NULL },\r
+ { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },\r
+ { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/\r
+ { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },\r
+ { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },\r
+ { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },\r
+ { "-colorTell", "colorTell", XrmoptionSepArg, NULL },\r
+ { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },\r
+ { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },\r
+ { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },\r
+ { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },\r
+ { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },\r
+ { "-soundShout", "soundShout", XrmoptionSepArg, NULL },\r
+ { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },\r
+ { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/\r
+ { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },\r
+ { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },\r
+ { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },\r
+ { "-soundTell", "soundTell", XrmoptionSepArg, NULL },\r
+ { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },\r
+ { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },\r
+ { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },\r
+ { "-soundMove", "soundMove", XrmoptionSepArg, NULL },\r
+ { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },\r
+ { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },\r
+ { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },\r
+ { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },\r
+ { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },\r
+ { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },\r
+ { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/\r
+ { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },\r
+ { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },\r
+ { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },\r
+ { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },\r
+ { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },\r
+ { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },\r
+ { "-animate", "animateMoving", XrmoptionNoArg, "True" },\r
+ { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },\r
+ { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },\r
+ { "-drag", "animateDragging", XrmoptionNoArg, "True" },\r
+ { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },\r
+ { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },\r
+ { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },\r
+ { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },\r
+ { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },\r
+ { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },\r
+ { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },\r
+ { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },\r
+ { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },\r
+ { "-initialMode", "initialMode", XrmoptionSepArg, NULL },\r
+ { "-mode", "initialMode", XrmoptionSepArg, NULL },\r
+ { "-variant", "variant", XrmoptionSepArg, NULL },\r
+ { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },\r
+ { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },\r
+ { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },\r
+ { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },\r
+ { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },\r
+ /* [AS,HR] New features */\r
+ { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },\r
+ { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },\r
+ { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },\r
+ { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },\r
+ { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },\r
+ { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },\r
+ { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },\r
+ // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c\r
+\r
+ /* [HGM,HR] User-selectable board size */\r
+ { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL }, \r
+ { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL }, \r
+ { "-matchPause", "matchPause", XrmoptionSepArg, NULL }, \r
+\r
+ /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */\r
+ { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work\r
+ { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL }, // requires front-end changes to work\r
+ { "-allWhite", "allWhite", XrmoptionSepArg, NULL }, // requires front-end changes to work\r
+ { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL }, \r
+ { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL }, \r
+ { "-testClaims", "testClaims", XrmoptionSepArg, NULL }, \r
+ { "-checkMates", "checkMates", XrmoptionSepArg, NULL }, \r
+ { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL }, \r
+ { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL }, \r
+ { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL }, \r
+ { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },\r
+ { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL }, \r
+ { "-userName", "userName", XrmoptionSepArg, NULL }, \r
+ { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" }, \r
+ { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL }, \r
+ { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL }, \r
+ { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL }, \r
+ { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL }, \r
+ { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL }, \r
+ { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL }, \r
+ { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL }, \r
+ { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL }, \r
+ { "-serverPause", "serverPause", XrmoptionSepArg, NULL }, \r
+ { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL }, \r
+};\r
+\r
+\r
+XtActionsRec boardActions[] = {\r
+ { "DrawPosition", DrawPositionProc },\r
+ { "HandleUserMove", HandleUserMove },\r
+ { "AnimateUserMove", AnimateUserMove },\r
+ { "FileNameAction", FileNameAction },\r
+ { "AskQuestionProc", AskQuestionProc },\r
+ { "AskQuestionReplyAction", AskQuestionReplyAction },\r
+ { "PieceMenuPopup", PieceMenuPopup },\r
+ { "WhiteClock", WhiteClock },\r
+ { "BlackClock", BlackClock },\r
+ { "Iconify", Iconify },\r
+ { "ResetProc", ResetProc },\r
+ { "LoadGameProc", LoadGameProc },\r
+ { "LoadNextGameProc", LoadNextGameProc },\r
+ { "LoadPrevGameProc", LoadPrevGameProc },\r
+ { "LoadSelectedProc", LoadSelectedProc },\r
+ { "ReloadGameProc", ReloadGameProc },\r
+ { "LoadPositionProc", LoadPositionProc },\r
+ { "LoadNextPositionProc", LoadNextPositionProc },\r
+ { "LoadPrevPositionProc", LoadPrevPositionProc },\r
+ { "ReloadPositionProc", ReloadPositionProc },\r
+ { "CopyPositionProc", CopyPositionProc },\r
+ { "PastePositionProc", PastePositionProc },\r
+ { "CopyGameProc", CopyGameProc },\r
+ { "PasteGameProc", PasteGameProc },\r
+ { "SaveGameProc", SaveGameProc },\r
+ { "SavePositionProc", SavePositionProc },\r
+ { "MailMoveProc", MailMoveProc },\r
+ { "ReloadCmailMsgProc", ReloadCmailMsgProc },\r
+ { "QuitProc", QuitProc },\r
+ { "MachineWhiteProc", MachineWhiteProc },\r
+ { "MachineBlackProc", MachineBlackProc },\r
+ { "AnalysisModeProc", AnalyzeModeProc },\r
+ { "AnalyzeFileProc", AnalyzeFileProc },\r
+ { "TwoMachinesProc", TwoMachinesProc },\r
+ { "IcsClientProc", IcsClientProc },\r
+ { "EditGameProc", EditGameProc },\r
+ { "EditPositionProc", EditPositionProc },\r
+ { "TrainingProc", EditPositionProc },\r
+ { "ShowGameListProc", ShowGameListProc },\r
+ { "ShowMoveListProc", HistoryShowProc},\r
+ { "EditTagsProc", EditCommentProc },\r
+ { "EditCommentProc", EditCommentProc },\r
+ { "IcsAlarmProc", IcsAlarmProc },\r
+ { "IcsInputBoxProc", IcsInputBoxProc },\r
+ { "PauseProc", PauseProc },\r
+ { "AcceptProc", AcceptProc },\r
+ { "DeclineProc", DeclineProc },\r
+ { "RematchProc", RematchProc },\r
+ { "CallFlagProc", CallFlagProc },\r
+ { "DrawProc", DrawProc },\r
+ { "AdjournProc", AdjournProc },\r
+ { "AbortProc", AbortProc },\r
+ { "ResignProc", ResignProc },\r
+ { "EnterKeyProc", EnterKeyProc },\r
+ { "StopObservingProc", StopObservingProc },\r
+ { "StopExaminingProc", StopExaminingProc },\r
+ { "BackwardProc", BackwardProc },\r
+ { "ForwardProc", ForwardProc },\r
+ { "ToStartProc", ToStartProc },\r
+ { "ToEndProc", ToEndProc },\r
+ { "RevertProc", RevertProc },\r
+ { "TruncateGameProc", TruncateGameProc },\r
+ { "MoveNowProc", MoveNowProc },\r
+ { "RetractMoveProc", RetractMoveProc },\r
+ { "AlwaysQueenProc", AlwaysQueenProc },\r
+ { "AnimateDraggingProc", AnimateDraggingProc },\r
+ { "AnimateMovingProc", AnimateMovingProc },\r
+ { "AutoflagProc", AutoflagProc },\r
+ { "AutoflipProc", AutoflipProc },\r
+ { "AutobsProc", AutobsProc },\r
+ { "AutoraiseProc", AutoraiseProc },\r
+ { "AutosaveProc", AutosaveProc },\r
+ { "BlindfoldProc", BlindfoldProc },\r
+ { "FlashMovesProc", FlashMovesProc },\r
+ { "FlipViewProc", FlipViewProc },\r
+ { "GetMoveListProc", GetMoveListProc },\r
+#if HIGHDRAG\r
+ { "HighlightDraggingProc", HighlightDraggingProc },\r
+#endif\r
+ { "HighlightLastMoveProc", HighlightLastMoveProc },\r
+ { "IcsAlarmProc", IcsAlarmProc },\r
+ { "MoveSoundProc", MoveSoundProc },\r
+ { "OldSaveStyleProc", OldSaveStyleProc },\r
+ { "PeriodicUpdatesProc", PeriodicUpdatesProc }, \r
+ { "PonderNextMoveProc", PonderNextMoveProc },\r
+ { "PopupExitMessageProc", PopupExitMessageProc }, \r
+ { "PopupMoveErrorsProc", PopupMoveErrorsProc }, \r
+ { "PremoveProc", PremoveProc },\r
+ { "QuietPlayProc", QuietPlayProc },\r
+ { "ShowCoordsProc", ShowCoordsProc },\r
+ { "ShowThinkingProc", ShowThinkingProc },\r
+ { "TestLegalityProc", TestLegalityProc },\r
+ { "InfoProc", InfoProc },\r
+ { "ManProc", ManProc },\r
+ { "HintProc", HintProc },\r
+ { "BookProc", BookProc },\r
+ { "AboutGameProc", AboutGameProc },\r
+ { "AboutProc", AboutProc },\r
+ { "DebugProc", DebugProc },\r
+ { "NothingProc", NothingProc },\r
+ { "CommentPopDown", (XtActionProc) CommentPopDown },\r
+ { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },\r
+ { "TagsPopDown", (XtActionProc) TagsPopDown },\r
+ { "ErrorPopDown", (XtActionProc) ErrorPopDown },\r
+ { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },\r
+ { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },\r
+ { "FileNamePopDown", (XtActionProc) FileNamePopDown },\r
+ { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },\r
+ { "GameListPopDown", (XtActionProc) GameListPopDown },\r
+ { "PromotionPopDown", (XtActionProc) PromotionPopDown },\r
+ { "HistoryPopDown", (XtActionProc) HistoryPopDown },\r
+};\r
+ \r
+char globalTranslations[] =\r
+ ":<Key>R: ResignProc() \n \\r
+ :<Key>r: ResetProc() \n \\r
+ :<Key>g: LoadGameProc() \n \\r
+ :<Key>N: LoadNextGameProc() \n \\r
+ :<Key>P: LoadPrevGameProc() \n \\r
+ :<Key>Q: QuitProc() \n \\r
+ :<Key>F: ToEndProc() \n \\r
+ :<Key>f: ForwardProc() \n \\r
+ :<Key>B: ToStartProc() \n \\r
+ :<Key>b: BackwardProc() \n \\r
+ :<Key>p: PauseProc() \n \\r
+ :<Key>d: DrawProc() \n \\r
+ :<Key>t: CallFlagProc() \n \\r
+ :<Key>i: Iconify() \n \\r
+ :<Key>c: Iconify() \n \\r
+ :<Key>v: FlipViewProc() \n \\r
+ <KeyDown>Control_L: BackwardProc() \n \\r
+ <KeyUp>Control_L: ForwardProc() \n \\r
+ <KeyDown>Control_R: BackwardProc() \n \\r
+ <KeyUp>Control_R: ForwardProc() \n \\r
+ Shift<Key>1: AskQuestionProc(\"Direct command\",\\r
+ \"Send to chess program:\",,1) \n \\r
+ Shift<Key>2: AskQuestionProc(\"Direct command\",\\r
+ \"Send to second chess program:\",,2) \n";\r
+\r
+char boardTranslations[] =\r
+ "<Btn1Down>: HandleUserMove() \n \\r
+ <Btn1Up>: HandleUserMove() \n \\r
+ <Btn1Motion>: AnimateUserMove() \n \\r
+ Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\\r
+ PieceMenuPopup(menuB) \n \\r
+ Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \\r
+ PieceMenuPopup(menuW) \n \\r
+ Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\\r
+ PieceMenuPopup(menuW) \n \\r
+ Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \\r
+ PieceMenuPopup(menuB) \n";\r
+ \r
+char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";\r
+char blackTranslations[] = "<BtnDown>: BlackClock()\n";\r
+ \r
+char ICSInputTranslations[] =\r
+ "<Key>Return: EnterKeyProc() \n";\r
+\r
+String xboardResources[] = {\r
+ "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",\r
+ "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",\r
+ "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",\r
+ NULL\r
+ };\r
+ \r
+\r
+/* Max possible square size */\r
+#define MAXSQSIZE 256\r
+\r
+static int xpm_avail[MAXSQSIZE];\r
+\r
+#ifdef HAVE_DIR_STRUCT\r
+\r
+/* Extract piece size from filename */\r
+static int\r
+xpm_getsize(name, len, ext)\r
+ char *name;\r
+ int len;\r
+ char *ext;\r
+{\r
+ char *p, *d;\r
+ char buf[10];\r
+ \r
+ if (len < 4)\r
+ return 0;\r
+\r
+ if ((p=strchr(name, '.')) == NULL ||\r
+ StrCaseCmp(p+1, ext) != 0)\r
+ return 0;\r
+ \r
+ p = name + 3;\r
+ d = buf;\r
+\r
+ while (*p && isdigit(*p))\r
+ *(d++) = *(p++);\r
+\r
+ *d = 0;\r
+ return atoi(buf);\r
+}\r
+\r
+/* Setup xpm_avail */\r
+static int\r
+xpm_getavail(dirname, ext)\r
+ char *dirname;\r
+ char *ext;\r
+{\r
+ DIR *dir;\r
+ struct dirent *ent;\r
+ int i;\r
+\r
+ for (i=0; i<MAXSQSIZE; ++i)\r
+ xpm_avail[i] = 0;\r
+\r
+ if (appData.debugMode)\r
+ fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);\r
+ \r
+ dir = opendir(dirname);\r
+ if (!dir)\r
+ {\r
+ fprintf(stderr, "%s: Can't access XPM directory %s\n", \r
+ programName, dirname);\r
+ exit(1);\r
+ }\r
+ \r
+ while ((ent=readdir(dir)) != NULL) {\r
+ i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);\r
+ if (i > 0 && i < MAXSQSIZE)\r
+ xpm_avail[i] = 1;\r
+ }\r
+\r
+ closedir(dir);\r
+\r
+ return 0;\r
+}\r
+\r
+void\r
+xpm_print_avail(fp, ext)\r
+ FILE *fp;\r
+ char *ext;\r
+{\r
+ int i;\r
+\r
+ fprintf(fp, "Available `%s' sizes:\n", ext);\r
+ for (i=1; i<MAXSQSIZE; ++i) {\r
+ if (xpm_avail[i])\r
+ printf("%d\n", i);\r
+ }\r
+}\r
+\r
+/* Return XPM piecesize closest to size */\r
+int\r
+xpm_closest_to(dirname, size, ext)\r
+ char *dirname;\r
+ int size;\r
+ char *ext;\r
+{\r
+ int i;\r
+ int sm_diff = MAXSQSIZE;\r
+ int sm_index = 0;\r
+ int diff;\r
+ \r
+ xpm_getavail(dirname, ext);\r
+\r
+ if (appData.debugMode)\r
+ xpm_print_avail(stderr, ext);\r
+ \r
+ for (i=1; i<MAXSQSIZE; ++i) {\r
+ if (xpm_avail[i]) {\r
+ diff = size - i;\r
+ diff = (diff<0) ? -diff : diff;\r
+ if (diff < sm_diff) {\r
+ sm_diff = diff;\r
+ sm_index = i;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!sm_index) {\r
+ fprintf(stderr, "Error: No `%s' files!\n", ext);\r
+ exit(1);\r
+ }\r
+\r
+ return sm_index;\r
+}\r
+#else /* !HAVE_DIR_STRUCT */\r
+/* If we are on a system without a DIR struct, we can't\r
+ read the directory, so we can't collect a list of\r
+ filenames, etc., so we can't do any size-fitting. */\r
+int\r
+xpm_closest_to(dirname, size, ext)\r
+ char *dirname;\r
+ int size;\r
+ char *ext;\r
+{\r
+ fprintf(stderr, "Warning: No DIR structure found on this system --\n");\r
+ fprintf(stderr, " Unable to autosize for XPM/XIM pieces.\n");\r
+ fprintf(stderr, " Please report this error to frankm@hiwaay.net.\n");\r
+ fprintf(stderr, " Include system type & operating system in message.\n");\r
+ return size;\r
+}\r
+#endif /* HAVE_DIR_STRUCT */\r
+\r
+static char *cnames[9] = { "black", "red", "green", "yellow", "blue",\r
+ "magenta", "cyan", "white" };\r
+typedef struct {\r
+ int attr, bg, fg;\r
+} TextColors;\r
+TextColors textColors[(int)NColorClasses];\r
+\r
+/* String is: "fg, bg, attr". Which is 0, 1, 2 */\r
+static int\r
+parse_color(str, which)\r
+ char *str;\r
+ int which;\r
+{\r
+ char *p, buf[100], *d;\r
+ int i;\r
+ \r
+ if (strlen(str) > 99) /* watch bounds on buf */\r
+ return -1;\r
+\r
+ p = str;\r
+ d = buf;\r
+ for (i=0; i<which; ++i) {\r
+ p = strchr(p, ',');\r
+ if (!p)\r
+ return -1;\r
+ ++p;\r
+ }\r
+\r
+ /* Could be looking at something like:\r
+ black, , 1\r
+ .. in which case we want to stop on a comma also */\r
+ while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))\r
+ ++p;\r
+\r
+ if (*p == ',') {\r
+ return -1; /* Use default for empty field */\r
+ }\r
+ \r
+ if (which == 2 || isdigit(*p))\r
+ return atoi(p);\r
+ \r
+ while (*p && isalpha(*p))\r
+ *(d++) = *(p++);\r
+\r
+ *d = 0;\r
+\r
+ for (i=0; i<8; ++i) {\r
+ if (!StrCaseCmp(buf, cnames[i]))\r
+ return which? (i+40) : (i+30);\r
+ }\r
+ if (!StrCaseCmp(buf, "default")) return -1;\r
+\r
+ fprintf(stderr, "%s: unrecognized color %s\n", programName, buf);\r
+ return -2;\r
+}\r
+\r
+static int\r
+parse_cpair(cc, str)\r
+ ColorClass cc;\r
+ char *str;\r
+{\r
+ if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {\r
+ fprintf(stderr, "%s: can't parse foreground color in `%s'\n",\r
+ programName, str);\r
+ return -1;\r
+ }\r
+\r
+ /* bg and attr are optional */\r
+ textColors[(int)cc].bg = parse_color(str, 1);\r
+ if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {\r
+ textColors[(int)cc].attr = 0;\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+/* Arrange to catch delete-window events */\r
+Atom wm_delete_window;\r
+void\r
+CatchDeleteWindow(Widget w, String procname)\r
+{\r
+ char buf[MSG_SIZ];\r
+ XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);\r
+ sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);\r
+ XtAugmentTranslations(w, XtParseTranslationTable(buf));\r
+}\r
+\r
+void\r
+BoardToTop()\r
+{\r
+ Arg args[16];\r
+ XtSetArg(args[0], XtNiconic, False);\r
+ XtSetValues(shellWidget, args, 1);\r
+\r
+ XtPopup(shellWidget, XtGrabNone); /* Raise if lowered */\r
+}\r
+\r
+#ifdef IDSIZES\r
+ // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined\r
+#else\r
+void InitDrawingSizes(BoardSize boardSize, int flags)\r
+{ // [HGM] Dummy routine to be able to link with backend files from 4.3.xx, which call it\r
+ ;\r
+}\r
+#endif\r
+\r
+int\r
+main(argc, argv)\r
+ int argc;\r
+ char **argv;\r
+{\r
+ int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;\r
+ XSetWindowAttributes window_attributes;\r
+ Arg args[16];\r
+ Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;\r
+ XrmValue vFrom, vTo;\r
+ XtGeometryResult gres;\r
+ char *p;\r
+ XrmDatabase xdb;\r
+ int forceMono = False;\r
+\r
+ setbuf(stdout, NULL);\r
+ setbuf(stderr, NULL);\r
+ debugFP = stderr;\r
+ \r
+ programName = strrchr(argv[0], '/');\r
+ if (programName == NULL)\r
+ programName = argv[0];\r
+ else\r
+ programName++;\r
+\r
+ shellWidget =\r
+ XtAppInitialize(&appContext, "XBoard", shellOptions,\r
+ XtNumber(shellOptions),\r
+ &argc, argv, xboardResources, NULL, 0);\r
+ if (argc > 1) {\r
+ fprintf(stderr, "%s: unrecognized argument %s\n",\r
+ programName, argv[1]);\r
+ exit(2);\r
+ }\r
+ \r
+ if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {\r
+ chessDir = ".";\r
+ } else {\r
+ if (chdir(chessDir) != 0) {\r
+ fprintf(stderr, "%s: can't cd to CHESSDIR: ", programName);\r
+ perror(chessDir);\r
+ exit(1);\r
+ }\r
+ }\r
+ \r
+ p = getenv("HOME");\r
+ if (p == NULL) p = "/tmp";\r
+ i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;\r
+ gameCopyFilename = (char*) malloc(i);\r
+ gamePasteFilename = (char*) malloc(i);\r
+ sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());\r
+ sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());\r
+\r
+ XtGetApplicationResources(shellWidget, (XtPointer) &appData,\r
+ clientResources, XtNumber(clientResources),\r
+ NULL, 0);\r
+\r
+ /* [HGM,HR] make sure board size is acceptable */\r
+ if(appData.NrFiles > BOARD_SIZE ||\r
+ appData.NrRanks > BOARD_SIZE )\r
+ DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2);\r
+\r
+ /* [HGM] The following line must be moved to the "New Shuffle Game" menu as soon as there is one! */\r
+ if(appData.defaultFrcPosition != -1) shuffleOpenings = TRUE;\r
+\r
+#if !HIGHDRAG\r
+ /* This feature does not work; animation needs a rewrite */\r
+ appData.highlightDragging = FALSE;\r
+#endif\r
+ InitBackEnd1();\r
+\r
+ xDisplay = XtDisplay(shellWidget);\r
+ xScreen = DefaultScreen(xDisplay);\r
+ wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);\r
+\r
+ gameInfo.variant = StringToVariant(appData.variant);\r
+ InitPosition(FALSE);\r
+#if 0\r
+ /*\r
+ * Determine boardSize\r
+ */\r
+ gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8\r
+\r
+//#ifndef IDSIZE\r
+ // [HGM] as long as we have not created the possibility to change size while running, start with requested size\r
+ gameInfo.boardWidth = appData.NrFiles > 0 ? appData.NrFiles : 8; \r
+ gameInfo.boardHeight = appData.NrRanks > 0 ? appData.NrRanks : 8;\r
+ gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;\r
+#endif\r
+\r
+\r
+#ifdef IDSIZE\r
+ InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine\r
+#else\r
+ if (isdigit(appData.boardSize[0])) {\r
+ i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,\r
+ &lineGap, &clockFontPxlSize, &coordFontPxlSize,\r
+ &fontPxlSize, &smallLayout, &tinyLayout);\r
+ if (i == 0) {\r
+ fprintf(stderr, "%s: bad boardSize syntax %s\n",\r
+ programName, appData.boardSize);\r
+ exit(2);\r
+ }\r
+ if (i < 7) {\r
+ /* Find some defaults; use the nearest known size */\r
+ SizeDefaults *szd, *nearest;\r
+ int distance = 99999;\r
+ nearest = szd = sizeDefaults;\r
+ while (szd->name != NULL) {\r
+ if (abs(szd->squareSize - squareSize) < distance) {\r
+ nearest = szd;\r
+ distance = abs(szd->squareSize - squareSize);\r
+ if (distance == 0) break;\r
+ }\r
+ szd++;\r
+ }\r
+ if (i < 2) lineGap = nearest->lineGap;\r
+ if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;\r
+ if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;\r
+ if (i < 5) fontPxlSize = nearest->fontPxlSize;\r
+ if (i < 6) smallLayout = nearest->smallLayout;\r
+ if (i < 7) tinyLayout = nearest->tinyLayout;\r
+ }\r
+ } else {\r
+ SizeDefaults *szd = sizeDefaults;\r
+ if (*appData.boardSize == NULLCHAR) {\r
+ while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||\r
+ DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {\r
+ szd++;\r
+ }\r
+ if (szd->name == NULL) szd--;\r
+ } else {\r
+ while (szd->name != NULL &&\r
+ StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;\r
+ if (szd->name == NULL) {\r
+ fprintf(stderr, "%s: unrecognized boardSize name %s\n",\r
+ programName, appData.boardSize);\r
+ exit(2);\r
+ }\r
+ }\r
+ squareSize = szd->squareSize;\r
+ lineGap = szd->lineGap;\r
+ clockFontPxlSize = szd->clockFontPxlSize;\r
+ coordFontPxlSize = szd->coordFontPxlSize;\r
+ fontPxlSize = szd->fontPxlSize;\r
+ smallLayout = szd->smallLayout;\r
+ tinyLayout = szd->tinyLayout;\r
+ }\r
+\r
+ /* Now, using squareSize as a hint, find a good XPM/XIM set size */\r
+ if (strlen(appData.pixmapDirectory) > 0) {\r
+ p = ExpandPathName(appData.pixmapDirectory);\r
+ if (!p) {\r
+ fprintf(stderr, "Error expanding path name \"%s\"\n",\r
+ appData.pixmapDirectory);\r
+ exit(1);\r
+ }\r
+ if (appData.debugMode) {\r
+ fprintf(stderr, "XBoard square size (hint): %d\n", squareSize);\r
+ fprintf(stderr, "%s fulldir:%s:\n", IMAGE_EXT, p);\r
+ }\r
+ squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);\r
+ if (appData.debugMode) {\r
+ fprintf(stderr, "Closest %s size: %d\n", IMAGE_EXT, squareSize);\r
+ }\r
+ }\r
+ \r
+ /* [HR] height treated separately (hacked) */\r
+ boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);\r
+ boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);\r
+ if (appData.showJail == 1) {\r
+ /* Jail on top and bottom */\r
+ XtSetArg(boardArgs[1], XtNwidth, boardWidth);\r
+ XtSetArg(boardArgs[2], XtNheight,\r
+ boardHeight + 2*(lineGap + squareSize));\r
+ } else if (appData.showJail == 2) {\r
+ /* Jail on sides */\r
+ XtSetArg(boardArgs[1], XtNwidth,\r
+ boardWidth + 2*(lineGap + squareSize));\r
+ XtSetArg(boardArgs[2], XtNheight, boardHeight);\r
+ } else {\r
+ /* No jail */\r
+ XtSetArg(boardArgs[1], XtNwidth, boardWidth);\r
+ XtSetArg(boardArgs[2], XtNheight, boardHeight);\r
+ }\r
+\r
+ /*\r
+ * Determine what fonts to use.\r
+ */\r
+ appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);\r
+ clockFontID = XLoadFont(xDisplay, appData.clockFont);\r
+ clockFontStruct = XQueryFont(xDisplay, clockFontID);\r
+ appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);\r
+ coordFontID = XLoadFont(xDisplay, appData.coordFont);\r
+ coordFontStruct = XQueryFont(xDisplay, coordFontID);\r
+ appData.font = FindFont(appData.font, fontPxlSize);\r
+\r
+ xdb = XtDatabase(xDisplay);\r
+ XrmPutStringResource(&xdb, "*font", appData.font);\r
+\r
+ /*\r
+ * Detect if there are not enough colors available and adapt.\r
+ */\r
+ if (DefaultDepth(xDisplay, xScreen) <= 2) {\r
+ appData.monoMode = True;\r
+ }\r
+\r
+ if (!appData.monoMode) {\r
+ vFrom.addr = (caddr_t) appData.lightSquareColor;\r
+ vFrom.size = strlen(appData.lightSquareColor);\r
+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
+ if (vTo.addr == NULL) {\r
+ appData.monoMode = True;\r
+ forceMono = True;\r
+ } else {\r
+ lightSquareColor = *(Pixel *) vTo.addr;\r
+ }\r
+ }\r
+ if (!appData.monoMode) {\r
+ vFrom.addr = (caddr_t) appData.darkSquareColor;\r
+ vFrom.size = strlen(appData.darkSquareColor);\r
+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
+ if (vTo.addr == NULL) {\r
+ appData.monoMode = True;\r
+ forceMono = True;\r
+ } else {\r
+ darkSquareColor = *(Pixel *) vTo.addr;\r
+ }\r
+ }\r
+ if (!appData.monoMode) {\r
+ vFrom.addr = (caddr_t) appData.whitePieceColor;\r
+ vFrom.size = strlen(appData.whitePieceColor);\r
+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
+ if (vTo.addr == NULL) {\r
+ appData.monoMode = True;\r
+ forceMono = True;\r
+ } else {\r
+ whitePieceColor = *(Pixel *) vTo.addr;\r
+ }\r
+ }\r
+ if (!appData.monoMode) {\r
+ vFrom.addr = (caddr_t) appData.blackPieceColor;\r
+ vFrom.size = strlen(appData.blackPieceColor);\r
+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
+ if (vTo.addr == NULL) {\r
+ appData.monoMode = True;\r
+ forceMono = True;\r
+ } else {\r
+ blackPieceColor = *(Pixel *) vTo.addr;\r
+ }\r
+ }\r
+\r
+ if (!appData.monoMode) {\r
+ vFrom.addr = (caddr_t) appData.highlightSquareColor;\r
+ vFrom.size = strlen(appData.highlightSquareColor);\r
+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
+ if (vTo.addr == NULL) {\r
+ appData.monoMode = True;\r
+ forceMono = True;\r
+ } else {\r
+ highlightSquareColor = *(Pixel *) vTo.addr;\r
+ }\r
+ }\r
+\r
+ if (!appData.monoMode) {\r
+ vFrom.addr = (caddr_t) appData.premoveHighlightColor;\r
+ vFrom.size = strlen(appData.premoveHighlightColor);\r
+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);\r
+ if (vTo.addr == NULL) {\r
+ appData.monoMode = True;\r
+ forceMono = True;\r
+ } else {\r
+ premoveHighlightColor = *(Pixel *) vTo.addr;\r
+ }\r
+ }\r
+\r
+ if (forceMono) {\r
+ fprintf(stderr, "%s: too few colors available; trying monochrome mode\n",\r
+ programName);\r
+ }\r
+\r
+ if (appData.monoMode && appData.debugMode) {\r
+ fprintf(stderr, "white pixel = 0x%lx, black pixel = 0x%lx\n",\r
+ (unsigned long) XWhitePixel(xDisplay, xScreen),\r
+ (unsigned long) XBlackPixel(xDisplay, xScreen));\r
+ }\r
+ \r
+ if (parse_cpair(ColorShout, appData.colorShout) < 0 ||\r
+ parse_cpair(ColorSShout, appData.colorSShout) < 0 ||\r
+ parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||\r
+ parse_cpair(ColorChannel, appData.colorChannel) < 0 ||\r
+ parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||\r
+ parse_cpair(ColorTell, appData.colorTell) < 0 ||\r
+ parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||\r
+ parse_cpair(ColorRequest, appData.colorRequest) < 0 ||\r
+ parse_cpair(ColorSeek, appData.colorSeek) < 0 ||\r
+ parse_cpair(ColorNormal, appData.colorNormal) < 0)\r
+ {\r
+ if (appData.colorize) {\r
+ fprintf(stderr,\r
+ "%s: can't parse color names; disabling colorization\n",\r
+ programName);\r
+ }\r
+ appData.colorize = FALSE;\r
+ }\r
+ textColors[ColorNone].fg = textColors[ColorNone].bg = -1;\r
+ textColors[ColorNone].attr = 0;\r
+ \r
+ XtAppAddActions(appContext, boardActions, XtNumber(boardActions));\r
+ \r
+ /*\r
+ * widget hierarchy\r
+ */\r
+ if (tinyLayout) {\r
+ layoutName = "tinyLayout";\r
+ } else if (smallLayout) {\r
+ layoutName = "smallLayout";\r
+ } else {\r
+ layoutName = "normalLayout";\r
+ }\r
+ /* Outer layoutWidget is there only to provide a name for use in\r
+ resources that depend on the layout style */\r
+ layoutWidget =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ formWidget =\r
+ XtCreateManagedWidget("form", formWidgetClass, layoutWidget,\r
+ formArgs, XtNumber(formArgs));\r
+ XtSetArg(args[0], XtNdefaultDistance, &sep);\r
+ XtGetValues(formWidget, args, 1);\r
+ \r
+ j = 0;\r
+ widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);\r
+\r
+ widgetList[j++] = whiteTimerWidget =\r
+ XtCreateWidget("whiteTime", labelWidgetClass,\r
+ formWidget, timerArgs, XtNumber(timerArgs));\r
+ XtSetArg(args[0], XtNfont, clockFontStruct);\r
+ XtSetValues(whiteTimerWidget, args, 1);\r
+ \r
+ widgetList[j++] = blackTimerWidget =\r
+ XtCreateWidget("blackTime", labelWidgetClass,\r
+ formWidget, timerArgs, XtNumber(timerArgs));\r
+ XtSetArg(args[0], XtNfont, clockFontStruct);\r
+ XtSetValues(blackTimerWidget, args, 1);\r
+ \r
+ if (appData.titleInWindow) {\r
+ widgetList[j++] = titleWidget = \r
+ XtCreateWidget("title", labelWidgetClass, formWidget,\r
+ titleArgs, XtNumber(titleArgs));\r
+ }\r
+\r
+ if (appData.showButtonBar) {\r
+ widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);\r
+ }\r
+\r
+ widgetList[j++] = messageWidget =\r
+ XtCreateWidget("message", labelWidgetClass, formWidget,\r
+ messageArgs, XtNumber(messageArgs));\r
+ \r
+ widgetList[j++] = boardWidget =\r
+ XtCreateWidget("board", widgetClass, formWidget, boardArgs,\r
+ XtNumber(boardArgs));\r
+\r
+ XtManageChildren(widgetList, j);\r
+ \r
+ timerWidth = (boardWidth - sep) / 2;\r
+ XtSetArg(args[0], XtNwidth, timerWidth);\r
+ XtSetValues(whiteTimerWidget, args, 1);\r
+ XtSetValues(blackTimerWidget, args, 1);\r
+ \r
+ XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);\r
+ XtSetArg(args[1], XtNforeground, &timerForegroundPixel);\r
+ XtGetValues(whiteTimerWidget, args, 2);\r
+ \r
+ if (appData.showButtonBar) {\r
+ XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);\r
+ XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);\r
+ XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);\r
+ }\r
+\r
+ /*\r
+ * formWidget uses these constraints but they are stored\r
+ * in the children.\r
+ */\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromHoriz, 0); i++;\r
+ XtSetValues(menuBarWidget, args, i);\r
+ if (appData.titleInWindow) {\r
+ if (smallLayout) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;\r
+ XtSetValues(whiteTimerWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;\r
+ XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;\r
+ XtSetValues(blackTimerWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;\r
+ XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;\r
+ XtSetValues(titleWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, titleWidget); i++;\r
+ XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;\r
+ XtSetValues(messageWidget, args, i);\r
+ if (appData.showButtonBar) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, titleWidget); i++;\r
+ XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;\r
+ XtSetValues(buttonBarWidget, args, i);\r
+ }\r
+ } else {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, titleWidget); i++;\r
+ XtSetValues(whiteTimerWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, titleWidget); i++;\r
+ XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;\r
+ XtSetValues(blackTimerWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;\r
+ XtSetValues(titleWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;\r
+ XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;\r
+ XtSetValues(messageWidget, args, i);\r
+ if (appData.showButtonBar) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;\r
+ XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;\r
+ XtSetValues(buttonBarWidget, args, i);\r
+ }\r
+ }\r
+ } else {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;\r
+ XtSetValues(whiteTimerWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;\r
+ XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;\r
+ XtSetValues(blackTimerWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;\r
+ XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;\r
+ XtSetValues(messageWidget, args, i);\r
+ if (appData.showButtonBar) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;\r
+ XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;\r
+ XtSetValues(buttonBarWidget, args, i);\r
+ }\r
+ }\r
+ i = 0;\r
+ XtSetArg(args[0], XtNfromVert, messageWidget);\r
+ XtSetValues(boardWidget, args, 1);\r
+\r
+ XtRealizeWidget(shellWidget);\r
+\r
+ /*\r
+ * Correct the width of the message and title widgets.\r
+ * It is not known why some systems need the extra fudge term.\r
+ * The value "2" is probably larger than needed.\r
+ */\r
+ XawFormDoLayout(formWidget, False);\r
+#define WIDTH_FUDGE 2\r
+ i = 0;\r
+ XtSetArg(args[i], XtNborderWidth, &bor); i++;\r
+ XtSetArg(args[i], XtNheight, &h); i++;\r
+ XtGetValues(messageWidget, args, i);\r
+ if (appData.showButtonBar) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNwidth, &w); i++;\r
+ XtGetValues(buttonBarWidget, args, i);\r
+ w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;\r
+ } else {\r
+ w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */\r
+ }\r
+\r
+ gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);\r
+ if (gres != XtGeometryYes && appData.debugMode) {\r
+ fprintf(stderr, "%s: messageWidget geometry error %d %d %d %d %d\n",\r
+ programName, gres, w, h, wr, hr);\r
+ }\r
+ \r
+ /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */\r
+ /* The size used for the child widget in layout lags one resize behind\r
+ its true size, so we resize a second time, 1 pixel smaller. Yeech! */\r
+ w--;\r
+ gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);\r
+ if (gres != XtGeometryYes && appData.debugMode) {\r
+ fprintf(stderr, "%s: messageWidget geometry error %d %d %d %d %d\n",\r
+ programName, gres, w, h, wr, hr);\r
+ }\r
+ /* !! end hack */\r
+\r
+ if (appData.titleInWindow) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNborderWidth, &bor); i++;\r
+ XtSetArg(args[i], XtNheight, &h); i++;\r
+ XtGetValues(titleWidget, args, i);\r
+ if (smallLayout) {\r
+ w = boardWidth - 2*bor;\r
+ } else {\r
+ XtSetArg(args[0], XtNwidth, &w);\r
+ XtGetValues(menuBarWidget, args, 1);\r
+ w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;\r
+ }\r
+\r
+ gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);\r
+ if (gres != XtGeometryYes && appData.debugMode) {\r
+ fprintf(stderr,\r
+ "%s: titleWidget geometry error %d %d %d %d %d\n",\r
+ programName, gres, w, h, wr, hr);\r
+ }\r
+ }\r
+ XawFormDoLayout(formWidget, True);\r
+\r
+ xBoardWindow = XtWindow(boardWidget);\r
+\r
+ // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would\r
+ // not need to go into InitDrawingSizes().\r
+#endif \r
+\r
+ /* \r
+ * Create X checkmark bitmap and initialize option menu checks.\r
+ */\r
+ ReadBitmap(&xMarkPixmap, "checkmark.bm",\r
+ checkmark_bits, checkmark_width, checkmark_height);\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ if (appData.alwaysPromoteToQueen) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),\r
+ args, 1);\r
+ }\r
+ if (appData.animateDragging) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Animate Dragging"),\r
+ args, 1);\r
+ }\r
+ if (appData.animate) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),\r
+ args, 1);\r
+ }\r
+ if (appData.autoComment) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),\r
+ args, 1);\r
+ }\r
+ if (appData.autoCallFlag) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),\r
+ args, 1);\r
+ }\r
+ if (appData.autoFlipView) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),\r
+ args, 1);\r
+ }\r
+ if (appData.autoObserve) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),\r
+ args, 1);\r
+ }\r
+ if (appData.autoRaiseBoard) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Auto Raise Board"), args, 1);\r
+ }\r
+ if (appData.autoSaveGames) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),\r
+ args, 1);\r
+ }\r
+ if (appData.saveGameFile[0] != NULLCHAR) {\r
+ /* Can't turn this off from menu */\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),\r
+ args, 1);\r
+ XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),\r
+ False);\r
+\r
+ }\r
+ if (appData.blindfold) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Blindfold"), args, 1);\r
+ }\r
+ if (appData.flashCount > 0) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Flash Moves"),\r
+ args, 1);\r
+ }\r
+ if (appData.getMoveList) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),\r
+ args, 1);\r
+ }\r
+#if HIGHDRAG\r
+ if (appData.highlightDragging) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Highlight Dragging"),\r
+ args, 1);\r
+ }\r
+#endif\r
+ if (appData.highlightLastMove) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Highlight Last Move"),\r
+ args, 1);\r
+ }\r
+ if (appData.icsAlarm) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),\r
+ args, 1);\r
+ }\r
+ if (appData.ringBellAfterMoves) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),\r
+ args, 1);\r
+ }\r
+ if (appData.oldSaveStyle) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Old Save Style"), args, 1);\r
+ }\r
+ if (appData.periodicUpdates) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Periodic Updates"), args, 1);\r
+ } \r
+ if (appData.ponderNextMove) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Ponder Next Move"), args, 1);\r
+ } \r
+ if (appData.popupExitMessage) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Popup Exit Message"), args, 1);\r
+ } \r
+ if (appData.popupMoveErrors) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Popup Move Errors"), args, 1);\r
+ } \r
+ if (appData.premove) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Premove"), args, 1);\r
+ }\r
+ if (appData.quietPlay) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Quiet Play"), args, 1);\r
+ }\r
+ if (appData.showCoords) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),\r
+ args, 1);\r
+ }\r
+ if (appData.showThinking) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),\r
+ args, 1);\r
+ }\r
+ if (appData.testLegality) {\r
+ XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),\r
+ args, 1);\r
+ }\r
+\r
+ /*\r
+ * Create an icon.\r
+ */\r
+ ReadBitmap(&wIconPixmap, "icon_white.bm",\r
+ icon_white_bits, icon_white_width, icon_white_height);\r
+ ReadBitmap(&bIconPixmap, "icon_black.bm",\r
+ icon_black_bits, icon_black_width, icon_black_height);\r
+ iconPixmap = wIconPixmap;\r
+ i = 0;\r
+ XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;\r
+ XtSetValues(shellWidget, args, i);\r
+ \r
+ /*\r
+ * Create a cursor for the board widget.\r
+ */\r
+ window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);\r
+ XChangeWindowAttributes(xDisplay, xBoardWindow,\r
+ CWCursor, &window_attributes);\r
+ \r
+ /*\r
+ * Inhibit shell resizing.\r
+ */\r
+ shellArgs[0].value = (XtArgVal) &w;\r
+ shellArgs[1].value = (XtArgVal) &h;\r
+ XtGetValues(shellWidget, shellArgs, 2);\r
+ shellArgs[4].value = shellArgs[2].value = w;\r
+ shellArgs[5].value = shellArgs[3].value = h;\r
+ XtSetValues(shellWidget, &shellArgs[2], 4);\r
+ \r
+ CatchDeleteWindow(shellWidget, "QuitProc");\r
+\r
+ CreateGCs();\r
+ CreateGrid();\r
+#if HAVE_LIBXPM\r
+ if (appData.bitmapDirectory[0] != NULLCHAR) {\r
+ CreatePieces();\r
+ } else {\r
+ CreateXPMPieces();\r
+ }\r
+#else\r
+ CreateXIMPieces();\r
+ /* Create regular pieces */\r
+ if (!useImages) CreatePieces();\r
+#endif \r
+\r
+ CreatePieceMenus();\r
+\r
+ if (appData.animate || appData.animateDragging)\r
+ CreateAnimVars();\r
+ \r
+ XtAugmentTranslations(formWidget,\r
+ XtParseTranslationTable(globalTranslations));\r
+ XtAugmentTranslations(boardWidget,\r
+ XtParseTranslationTable(boardTranslations));\r
+ XtAugmentTranslations(whiteTimerWidget,\r
+ XtParseTranslationTable(whiteTranslations));\r
+ XtAugmentTranslations(blackTimerWidget,\r
+ XtParseTranslationTable(blackTranslations));\r
+\r
+ /* Why is the following needed on some versions of X instead\r
+ * of a translation? */\r
+ XtAddEventHandler(boardWidget, ExposureMask, False,\r
+ (XtEventHandler) EventProc, NULL);\r
+ /* end why */\r
+\r
+ InitBackEnd2();\r
+ \r
+ if (errorExitStatus == -1) {\r
+ if (appData.icsActive) {\r
+ /* We now wait until we see "login:" from the ICS before\r
+ sending the logon script (problems with timestamp otherwise) */\r
+ /*ICSInitScript();*/\r
+ if (appData.icsInputBox) ICSInputBoxPopUp();\r
+ }\r
+\r
+ signal(SIGINT, IntSigHandler);\r
+ signal(SIGTERM, IntSigHandler);\r
+ if (*appData.cmailGameName != NULLCHAR) {\r
+ signal(SIGUSR1, CmailSigHandler);\r
+ }\r
+ }\r
+ InitPosition(TRUE);\r
+\r
+ XtAppMainLoop(appContext);\r
+ return 0;\r
+}\r
+\r
+void\r
+ShutDownFrontEnd()\r
+{\r
+ if (appData.icsActive && oldICSInteractionTitle != NULL) {\r
+ DisplayIcsInteractionTitle(oldICSInteractionTitle);\r
+ }\r
+ unlink(gameCopyFilename);\r
+ unlink(gamePasteFilename);\r
+}\r
+\r
+RETSIGTYPE\r
+IntSigHandler(sig)\r
+ int sig;\r
+{\r
+ ExitEvent(sig);\r
+}\r
+\r
+RETSIGTYPE\r
+CmailSigHandler(sig)\r
+ int sig;\r
+{\r
+ int dummy = 0;\r
+ int error;\r
+\r
+ signal(SIGUSR1, SIG_IGN); /* suspend handler */\r
+\r
+ /* Activate call-back function CmailSigHandlerCallBack() */\r
+ OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);\r
+\r
+ signal(SIGUSR1, CmailSigHandler); /* re-activate handler */\r
+}\r
+\r
+void\r
+CmailSigHandlerCallBack(isr, closure, message, count, error)\r
+ InputSourceRef isr;\r
+ VOIDSTAR closure;\r
+ char *message;\r
+ int count;\r
+ int error;\r
+{\r
+ BoardToTop();\r
+ ReloadCmailMsgEvent(TRUE); /* Reload cmail msg */\r
+}\r
+/**** end signal code ****/\r
+\r
+\r
+void\r
+ICSInitScript()\r
+{\r
+ FILE *f;\r
+ char buf[MSG_SIZ];\r
+ char *p;\r
+\r
+ f = fopen(appData.icsLogon, "r");\r
+ if (f == NULL) {\r
+ p = getenv("HOME");\r
+ if (p != NULL) {\r
+ strcpy(buf, p);\r
+ strcat(buf, "/");\r
+ strcat(buf, appData.icsLogon);\r
+ f = fopen(buf, "r");\r
+ }\r
+ }\r
+ if (f != NULL)\r
+ ProcessICSInitScript(f);\r
+}\r
+\r
+void\r
+ResetFrontEnd()\r
+{\r
+ CommentPopDown();\r
+ EditCommentPopDown();\r
+ TagsPopDown();\r
+ return;\r
+}\r
+\r
+typedef struct {\r
+ char *name;\r
+ Boolean value;\r
+} Enables;\r
+\r
+void\r
+SetMenuEnables(enab)\r
+ Enables *enab;\r
+{\r
+ Widget w;\r
+ if (!menuBarWidget) return;\r
+ while (enab->name != NULL) {\r
+ w = XtNameToWidget(menuBarWidget, enab->name);\r
+ if (w == NULL) {\r
+ DisplayError(enab->name, 0);\r
+ } else {\r
+ XtSetSensitive(w, enab->value);\r
+ }\r
+ enab++;\r
+ }\r
+}\r
+\r
+Enables icsEnables[] = {\r
+ { "menuFile.Mail Move", False },\r
+ { "menuFile.Reload CMail Message", False },\r
+ { "menuMode.Machine Black", False },\r
+ { "menuMode.Machine White", False },\r
+ { "menuMode.Analysis Mode", False },\r
+ { "menuMode.Analyze File", False },\r
+ { "menuMode.Two Machines", False },\r
+#ifndef ZIPPY\r
+ { "menuHelp.Hint", False },\r
+ { "menuHelp.Book", False },\r
+ { "menuStep.Move Now", False },\r
+ { "menuOptions.Periodic Updates", False }, \r
+ { "menuOptions.Show Thinking", False },\r
+ { "menuOptions.Ponder Next Move", False },\r
+#endif\r
+ { NULL, False }\r
+};\r
+\r
+Enables ncpEnables[] = { \r
+ { "menuFile.Mail Move", False },\r
+ { "menuFile.Reload CMail Message", False },\r
+ { "menuMode.Machine White", False },\r
+ { "menuMode.Machine Black", False },\r
+ { "menuMode.Analysis Mode", False },\r
+ { "menuMode.Analyze File", False },\r
+ { "menuMode.Two Machines", False },\r
+ { "menuMode.ICS Client", False },\r
+ { "menuMode.ICS Input Box", False },\r
+ { "Action", False },\r
+ { "menuStep.Revert", False },\r
+ { "menuStep.Move Now", False },\r
+ { "menuStep.Retract Move", False },\r
+ { "menuOptions.Auto Comment", False },\r
+ { "menuOptions.Auto Flag", False },\r
+ { "menuOptions.Auto Flip View", False },\r
+ { "menuOptions.Auto Observe", False },\r
+ { "menuOptions.Auto Raise Board", False },\r
+ { "menuOptions.Get Move List", False },\r
+ { "menuOptions.ICS Alarm", False },\r
+ { "menuOptions.Move Sound", False },\r
+ { "menuOptions.Quiet Play", False },\r
+ { "menuOptions.Show Thinking", False },\r
+ { "menuOptions.Periodic Updates", False }, \r
+ { "menuOptions.Ponder Next Move", False },\r
+ { "menuHelp.Hint", False },\r
+ { "menuHelp.Book", False },\r
+ { NULL, False }\r
+};\r
+\r
+Enables gnuEnables[] = { \r
+ { "menuMode.ICS Client", False },\r
+ { "menuMode.ICS Input Box", False },\r
+ { "menuAction.Accept", False },\r
+ { "menuAction.Decline", False },\r
+ { "menuAction.Rematch", False },\r
+ { "menuAction.Adjourn", False },\r
+ { "menuAction.Stop Examining", False },\r
+ { "menuAction.Stop Observing", False },\r
+ { "menuStep.Revert", False },\r
+ { "menuOptions.Auto Comment", False },\r
+ { "menuOptions.Auto Observe", False },\r
+ { "menuOptions.Auto Raise Board", False },\r
+ { "menuOptions.Get Move List", False },\r
+ { "menuOptions.Premove", False },\r
+ { "menuOptions.Quiet Play", False },\r
+\r
+ /* The next two options rely on SetCmailMode being called *after* */\r
+ /* SetGNUMode so that when GNU is being used to give hints these */\r
+ /* menu options are still available */\r
+\r
+ { "menuFile.Mail Move", False },\r
+ { "menuFile.Reload CMail Message", False },\r
+ { NULL, False }\r
+};\r
+\r
+Enables cmailEnables[] = { \r
+ { "Action", True },\r
+ { "menuAction.Call Flag", False },\r
+ { "menuAction.Draw", True },\r
+ { "menuAction.Adjourn", False },\r
+ { "menuAction.Abort", False },\r
+ { "menuAction.Stop Observing", False },\r
+ { "menuAction.Stop Examining", False },\r
+ { "menuFile.Mail Move", True },\r
+ { "menuFile.Reload CMail Message", True },\r
+ { NULL, False }\r
+};\r
+\r
+Enables trainingOnEnables[] = { \r
+ { "menuMode.Edit Comment", False },\r
+ { "menuMode.Pause", False },\r
+ { "menuStep.Forward", False },\r
+ { "menuStep.Backward", False },\r
+ { "menuStep.Forward to End", False },\r
+ { "menuStep.Back to Start", False },\r
+ { "menuStep.Move Now", False },\r
+ { "menuStep.Truncate Game", False },\r
+ { NULL, False }\r
+};\r
+\r
+Enables trainingOffEnables[] = { \r
+ { "menuMode.Edit Comment", True },\r
+ { "menuMode.Pause", True },\r
+ { "menuStep.Forward", True },\r
+ { "menuStep.Backward", True },\r
+ { "menuStep.Forward to End", True },\r
+ { "menuStep.Back to Start", True },\r
+ { "menuStep.Move Now", True },\r
+ { "menuStep.Truncate Game", True },\r
+ { NULL, False }\r
+};\r
+\r
+Enables machineThinkingEnables[] = {\r
+ { "menuFile.Load Game", False },\r
+ { "menuFile.Load Next Game", False },\r
+ { "menuFile.Load Previous Game", False },\r
+ { "menuFile.Reload Same Game", False },\r
+ { "menuFile.Paste Game", False },\r
+ { "menuFile.Load Position", False },\r
+ { "menuFile.Load Next Position", False },\r
+ { "menuFile.Load Previous Position", False },\r
+ { "menuFile.Reload Same Position", False },\r
+ { "menuFile.Paste Position", False },\r
+ { "menuMode.Machine White", False },\r
+ { "menuMode.Machine Black", False },\r
+ { "menuMode.Two Machines", False },\r
+ { "menuStep.Retract Move", False },\r
+ { NULL, False }\r
+};\r
+\r
+Enables userThinkingEnables[] = {\r
+ { "menuFile.Load Game", True },\r
+ { "menuFile.Load Next Game", True },\r
+ { "menuFile.Load Previous Game", True },\r
+ { "menuFile.Reload Same Game", True },\r
+ { "menuFile.Paste Game", True },\r
+ { "menuFile.Load Position", True },\r
+ { "menuFile.Load Next Position", True },\r
+ { "menuFile.Load Previous Position", True },\r
+ { "menuFile.Reload Same Position", True },\r
+ { "menuFile.Paste Position", True },\r
+ { "menuMode.Machine White", True },\r
+ { "menuMode.Machine Black", True },\r
+ { "menuMode.Two Machines", True },\r
+ { "menuStep.Retract Move", True },\r
+ { NULL, False }\r
+};\r
+\r
+void SetICSMode()\r
+{\r
+ SetMenuEnables(icsEnables);\r
+}\r
+\r
+void\r
+SetNCPMode()\r
+{\r
+ SetMenuEnables(ncpEnables);\r
+}\r
+\r
+void\r
+SetGNUMode()\r
+{\r
+ SetMenuEnables(gnuEnables);\r
+}\r
+\r
+void\r
+SetCmailMode()\r
+{\r
+ SetMenuEnables(cmailEnables);\r
+}\r
+\r
+void\r
+SetTrainingModeOn()\r
+{\r
+ SetMenuEnables(trainingOnEnables);\r
+ if (appData.showButtonBar) {\r
+ XtSetSensitive(buttonBarWidget, False);\r
+ }\r
+ CommentPopDown();\r
+}\r
+\r
+void\r
+SetTrainingModeOff()\r
+{\r
+ SetMenuEnables(trainingOffEnables);\r
+ if (appData.showButtonBar) {\r
+ XtSetSensitive(buttonBarWidget, True);\r
+ }\r
+}\r
+\r
+void\r
+SetUserThinkingEnables()\r
+{\r
+ if (appData.noChessProgram) return;\r
+ SetMenuEnables(userThinkingEnables);\r
+}\r
+\r
+void\r
+SetMachineThinkingEnables()\r
+{\r
+ if (appData.noChessProgram) return;\r
+ SetMenuEnables(machineThinkingEnables);\r
+ switch (gameMode) {\r
+ case MachinePlaysBlack:\r
+ case MachinePlaysWhite:\r
+ case TwoMachinesPlay:\r
+ XtSetSensitive(XtNameToWidget(menuBarWidget,\r
+ ModeToWidgetName(gameMode)), True);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+#define Abs(n) ((n)<0 ? -(n) : (n))\r
+\r
+/*\r
+ * Find a font that matches "pattern" that is as close as\r
+ * possible to the targetPxlSize. Prefer fonts that are k\r
+ * pixels smaller to fonts that are k pixels larger. The\r
+ * pattern must be in the X Consortium standard format, \r
+ * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".\r
+ * The return value should be freed with XtFree when no\r
+ * longer needed.\r
+ */\r
+char *FindFont(pattern, targetPxlSize)\r
+ char *pattern;\r
+ int targetPxlSize;\r
+{\r
+ char **fonts, *p, *best, *scalable, *scalableTail;\r
+ int i, j, nfonts, minerr, err, pxlSize;\r
+\r
+ fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);\r
+ if (nfonts < 1) {\r
+ fprintf(stderr, "%s: no fonts match pattern %s\n",\r
+ programName, pattern);\r
+ exit(2);\r
+ }\r
+ best = fonts[0];\r
+ scalable = NULL;\r
+ minerr = 999999;\r
+ for (i=0; i<nfonts; i++) {\r
+ j = 0;\r
+ p = fonts[i];\r
+ if (*p != '-') continue;\r
+ while (j < 7) {\r
+ if (*p == NULLCHAR) break;\r
+ if (*p++ == '-') j++;\r
+ }\r
+ if (j < 7) continue;\r
+ pxlSize = atoi(p);\r
+ if (pxlSize == 0) {\r
+ scalable = fonts[i];\r
+ scalableTail = p;\r
+ } else {\r
+ err = pxlSize - targetPxlSize;\r
+ if (Abs(err) < Abs(minerr) ||\r
+ (minerr > 0 && err < 0 && -err == minerr)) {\r
+ best = fonts[i];\r
+ minerr = err;\r
+ }\r
+ }\r
+ }\r
+ if (scalable && Abs(minerr) > appData.fontSizeTolerance) {\r
+ /* If the error is too big and there is a scalable font,\r
+ use the scalable font. */\r
+ int headlen = scalableTail - scalable;\r
+ p = (char *) XtMalloc(strlen(scalable) + 10);\r
+ while (isdigit(*scalableTail)) scalableTail++;\r
+ sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);\r
+ } else {\r
+ p = (char *) XtMalloc(strlen(best) + 1);\r
+ strcpy(p, best);\r
+ }\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "resolved %s at pixel size %d\n to %s\n",\r
+ pattern, targetPxlSize, p);\r
+ }\r
+ XFreeFontNames(fonts);\r
+ return p;\r
+}\r
+\r
+void CreateGCs()\r
+{\r
+ XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground\r
+ | GCBackground | GCFunction | GCPlaneMask;\r
+ XGCValues gc_values;\r
+ GC copyInvertedGC;\r
+ \r
+ gc_values.plane_mask = AllPlanes;\r
+ gc_values.line_width = lineGap;\r
+ gc_values.line_style = LineSolid;\r
+ gc_values.function = GXcopy;\r
+ \r
+ gc_values.foreground = XBlackPixel(xDisplay, xScreen);\r
+ gc_values.background = XBlackPixel(xDisplay, xScreen);\r
+ lineGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ \r
+ gc_values.foreground = XBlackPixel(xDisplay, xScreen);\r
+ gc_values.background = XWhitePixel(xDisplay, xScreen);\r
+ coordGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ XSetFont(xDisplay, coordGC, coordFontID);\r
+ \r
+ if (appData.monoMode) {\r
+ gc_values.foreground = XWhitePixel(xDisplay, xScreen);\r
+ gc_values.background = XWhitePixel(xDisplay, xScreen);\r
+ highlineGC = XtGetGC(shellWidget, value_mask, &gc_values); \r
+\r
+ gc_values.foreground = XWhitePixel(xDisplay, xScreen);\r
+ gc_values.background = XBlackPixel(xDisplay, xScreen);\r
+ lightSquareGC = wbPieceGC \r
+ = XtGetGC(shellWidget, value_mask, &gc_values);\r
+\r
+ gc_values.foreground = XBlackPixel(xDisplay, xScreen);\r
+ gc_values.background = XWhitePixel(xDisplay, xScreen);\r
+ darkSquareGC = bwPieceGC\r
+ = XtGetGC(shellWidget, value_mask, &gc_values);\r
+\r
+ if (DefaultDepth(xDisplay, xScreen) == 1) {\r
+ /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */\r
+ gc_values.function = GXcopyInverted;\r
+ copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ gc_values.function = GXcopy;\r
+ if (XBlackPixel(xDisplay, xScreen) == 1) {\r
+ bwPieceGC = darkSquareGC;\r
+ wbPieceGC = copyInvertedGC;\r
+ } else {\r
+ bwPieceGC = copyInvertedGC;\r
+ wbPieceGC = lightSquareGC;\r
+ }\r
+ }\r
+ } else {\r
+ gc_values.foreground = highlightSquareColor;\r
+ gc_values.background = highlightSquareColor;\r
+ highlineGC = XtGetGC(shellWidget, value_mask, &gc_values); \r
+\r
+ gc_values.foreground = premoveHighlightColor;\r
+ gc_values.background = premoveHighlightColor;\r
+ prelineGC = XtGetGC(shellWidget, value_mask, &gc_values); \r
+\r
+ gc_values.foreground = lightSquareColor;\r
+ gc_values.background = darkSquareColor;\r
+ lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ \r
+ gc_values.foreground = darkSquareColor;\r
+ gc_values.background = lightSquareColor;\r
+ darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+\r
+ gc_values.foreground = jailSquareColor;\r
+ gc_values.background = jailSquareColor;\r
+ jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+\r
+ gc_values.foreground = whitePieceColor;\r
+ gc_values.background = darkSquareColor;\r
+ wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ \r
+ gc_values.foreground = whitePieceColor;\r
+ gc_values.background = lightSquareColor;\r
+ wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ \r
+ gc_values.foreground = whitePieceColor;\r
+ gc_values.background = jailSquareColor;\r
+ wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ \r
+ gc_values.foreground = blackPieceColor;\r
+ gc_values.background = darkSquareColor;\r
+ bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ \r
+ gc_values.foreground = blackPieceColor;\r
+ gc_values.background = lightSquareColor;\r
+ blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+\r
+ gc_values.foreground = blackPieceColor;\r
+ gc_values.background = jailSquareColor;\r
+ bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);\r
+ }\r
+}\r
+\r
+void loadXIM(xim, xmask, filename, dest, mask)\r
+ XImage *xim;\r
+ XImage *xmask;\r
+ char *filename;\r
+ Pixmap *dest;\r
+ Pixmap *mask;\r
+{\r
+ int x, y, w, h, p;\r
+ FILE *fp;\r
+ Pixmap temp;\r
+ XGCValues values;\r
+ GC maskGC;\r
+\r
+ fp = fopen(filename, "rb");\r
+ if (!fp) {\r
+ fprintf(stderr, "%s: error loading XIM!\n", programName);\r
+ exit(1);\r
+ }\r
+ \r
+ w = fgetc(fp);\r
+ h = fgetc(fp);\r
+ \r
+ for (y=0; y<h; ++y) {\r
+ for (x=0; x<h; ++x) {\r
+ p = fgetc(fp);\r
+\r
+ switch (p) {\r
+ case 0: \r
+ XPutPixel(xim, x, y, blackPieceColor); \r
+ if (xmask)\r
+ XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));\r
+ break;\r
+ case 1: \r
+ XPutPixel(xim, x, y, darkSquareColor); \r
+ if (xmask)\r
+ XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));\r
+ break;\r
+ case 2: \r
+ XPutPixel(xim, x, y, whitePieceColor); \r
+ if (xmask)\r
+ XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));\r
+ break;\r
+ case 3: \r
+ XPutPixel(xim, x, y, lightSquareColor);\r
+ if (xmask)\r
+ XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* create Pixmap of piece */\r
+ *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),\r
+ w, h, xim->depth);\r
+ XPutImage(xDisplay, *dest, lightSquareGC, xim,\r
+ 0, 0, 0, 0, w, h); \r
+\r
+ /* create Pixmap of clipmask \r
+ Note: We assume the white/black pieces have the same\r
+ outline, so we make only 6 masks. This is okay\r
+ since the XPM clipmask routines do the same. */\r
+ if (xmask) {\r
+ temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),\r
+ w, h, xim->depth);\r
+ XPutImage(xDisplay, temp, lightSquareGC, xmask,\r
+ 0, 0, 0, 0, w, h); \r
+\r
+ /* now create the 1-bit version */\r
+ *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),\r
+ w, h, 1);\r
+\r
+ values.foreground = 1;\r
+ values.background = 0;\r
+\r
+ /* Don't use XtGetGC, not read only */\r
+ maskGC = XCreateGC(xDisplay, *mask, \r
+ GCForeground | GCBackground, &values);\r
+ XCopyPlane(xDisplay, temp, *mask, maskGC, \r
+ 0, 0, squareSize, squareSize, 0, 0, 1);\r
+ XFreePixmap(xDisplay, temp);\r
+ }\r
+}\r
+\r
+void CreateXIMPieces()\r
+{\r
+ int piece, kind;\r
+ char buf[MSG_SIZ];\r
+ u_int ss;\r
+ static char *ximkind[] = { "ll", "ld", "dl", "dd" };\r
+ XImage *ximtemp;\r
+\r
+ ss = squareSize;\r
+\r
+ /* The XSynchronize calls were copied from CreatePieces.\r
+ Not sure if needed, but can't hurt */\r
+ XSynchronize(xDisplay, True); /* Work-around for xlib/xt\r
+ buffering bug */\r
+ \r
+ /* temp needed by loadXIM() */\r
+ ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),\r
+ 0, 0, ss, ss, AllPlanes, XYPixmap);\r
+\r
+ if (strlen(appData.pixmapDirectory) == 0) {\r
+ useImages = 0;\r
+ } else {\r
+ useImages = 1;\r
+ if (appData.monoMode) {\r
+ DisplayFatalError("XIM pieces cannot be used in monochrome mode",\r
+ 0, 2);\r
+ ExitEvent(2);\r
+ }\r
+ fprintf(stderr, "\nLoading XIMs...\n");\r
+ /* Load pieces */\r
+ for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {\r
+ fprintf(stderr, "%d", piece+1);\r
+ for (kind=0; kind<4; kind++) {\r
+ fprintf(stderr, ".");\r
+ sprintf(buf, "%s/%c%s%u.xim",\r
+ ExpandPathName(appData.pixmapDirectory),\r
+ ToLower(PieceToChar((ChessSquare)piece)),\r
+ ximkind[kind], ss);\r
+ ximPieceBitmap[kind][piece] =\r
+ XGetImage(xDisplay, DefaultRootWindow(xDisplay),\r
+ 0, 0, ss, ss, AllPlanes, XYPixmap);\r
+ if (appData.debugMode)\r
+ fprintf(stderr, "(File:%s:) ", buf);\r
+ loadXIM(ximPieceBitmap[kind][piece], \r
+ ximtemp, buf,\r
+ &(xpmPieceBitmap[kind][piece]),\r
+ &(ximMaskPm[piece%(int)BlackPawn]));\r
+ }\r
+ fprintf(stderr," ");\r
+ }\r
+ /* Load light and dark squares */\r
+ /* If the LSQ and DSQ pieces don't exist, we will \r
+ draw them with solid squares. */\r
+ sprintf(buf, "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);\r
+ if (access(buf, 0) != 0) {\r
+ useImageSqs = 0;\r
+ } else {\r
+ useImageSqs = 1;\r
+ fprintf(stderr, "light square ");\r
+ ximLightSquare= \r
+ XGetImage(xDisplay, DefaultRootWindow(xDisplay),\r
+ 0, 0, ss, ss, AllPlanes, XYPixmap);\r
+ if (appData.debugMode)\r
+ fprintf(stderr, "(File:%s:) ", buf);\r
+\r
+ loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);\r
+ fprintf(stderr, "dark square ");\r
+ sprintf(buf, "%s/dsq%u.xim",\r
+ ExpandPathName(appData.pixmapDirectory), ss);\r
+ if (appData.debugMode)\r
+ fprintf(stderr, "(File:%s:) ", buf);\r
+ ximDarkSquare= \r
+ XGetImage(xDisplay, DefaultRootWindow(xDisplay),\r
+ 0, 0, ss, ss, AllPlanes, XYPixmap);\r
+ loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);\r
+ xpmJailSquare = xpmLightSquare;\r
+ }\r
+ fprintf(stderr, "Done.\n");\r
+ }\r
+ XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */\r
+}\r
+\r
+#if HAVE_LIBXPM\r
+void CreateXPMPieces()\r
+{\r
+ int piece, kind, r;\r
+ char buf[MSG_SIZ];\r
+ u_int ss = squareSize;\r
+ XpmAttributes attr;\r
+ static char *xpmkind[] = { "ll", "ld", "dl", "dd" };\r
+ XpmColorSymbol symbols[4];\r
+\r
+#if 0\r
+ /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */\r
+ if (appData.debugMode) {\r
+ fprintf(stderr, "XPM Library Version: %d.%d%c\n", \r
+ XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));\r
+ }\r
+#endif\r
+ \r
+ /* The XSynchronize calls were copied from CreatePieces.\r
+ Not sure if needed, but can't hurt */\r
+ XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */\r
+ \r
+ /* Setup translations so piece colors match square colors */\r
+ symbols[0].name = "light_piece";\r
+ symbols[0].value = appData.whitePieceColor;\r
+ symbols[1].name = "dark_piece";\r
+ symbols[1].value = appData.blackPieceColor;\r
+ symbols[2].name = "light_square";\r
+ symbols[2].value = appData.lightSquareColor;\r
+ symbols[3].name = "dark_square";\r
+ symbols[3].value = appData.darkSquareColor;\r
+\r
+ attr.valuemask = XpmColorSymbols;\r
+ attr.colorsymbols = symbols;\r
+ attr.numsymbols = 4;\r
+\r
+ if (appData.monoMode) {\r
+ DisplayFatalError("XPM pieces cannot be used in monochrome mode",\r
+ 0, 2);\r
+ ExitEvent(2);\r
+ }\r
+ if (strlen(appData.pixmapDirectory) == 0) {\r
+ XpmPieces* pieces = builtInXpms;\r
+ useImages = 1;\r
+ /* Load pieces */\r
+ while (pieces->size != squareSize && pieces->size) pieces++;\r
+ if (!pieces->size) {\r
+ fprintf(stderr, "No builtin XPM pieces of size %d\n", squareSize);\r
+ exit(1);\r
+ }\r
+ for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {\r
+ for (kind=0; kind<4; kind++) {\r
+\r
+ if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,\r
+ pieces->xpm[piece][kind],\r
+ &(xpmPieceBitmap[kind][piece]),\r
+ NULL, &attr)) != 0) {\r
+ fprintf(stderr, "Error %d loading XPM image \"%s\"\n",\r
+ r, buf);\r
+ exit(1); \r
+ } \r
+ } \r
+ }\r
+ useImageSqs = 0;\r
+ xpmJailSquare = xpmLightSquare;\r
+ } else {\r
+ useImages = 1;\r
+ \r
+ fprintf(stderr, "\nLoading XPMs...\n");\r
+\r
+ /* Load pieces */\r
+ for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {\r
+ fprintf(stderr, "%d ", piece+1);\r
+ for (kind=0; kind<4; kind++) {\r
+ sprintf(buf, "%s/%c%s%u.xpm",\r
+ ExpandPathName(appData.pixmapDirectory),\r
+ ToLower(PieceToChar((ChessSquare)piece)),\r
+ xpmkind[kind], ss);\r
+ if (appData.debugMode) {\r
+ fprintf(stderr, "(File:%s:) ", buf);\r
+ }\r
+ if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,\r
+ &(xpmPieceBitmap[kind][piece]),\r
+ NULL, &attr)) != 0) {\r
+ fprintf(stderr, "Error %d loading XPM file \"%s\"\n",\r
+ r, buf);\r
+ exit(1); \r
+ } \r
+ } \r
+ }\r
+ /* Load light and dark squares */\r
+ /* If the LSQ and DSQ pieces don't exist, we will \r
+ draw them with solid squares. */\r
+ fprintf(stderr, "light square ");\r
+ sprintf(buf, "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);\r
+ if (access(buf, 0) != 0) {\r
+ useImageSqs = 0;\r
+ } else {\r
+ useImageSqs = 1;\r
+ if (appData.debugMode)\r
+ fprintf(stderr, "(File:%s:) ", buf);\r
+\r
+ if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,\r
+ &xpmLightSquare, NULL, &attr)) != 0) {\r
+ fprintf(stderr, "Error %d loading XPM file \"%s\"\n", r, buf);\r
+ exit(1);\r
+ }\r
+ fprintf(stderr, "dark square ");\r
+ sprintf(buf, "%s/dsq%u.xpm",\r
+ ExpandPathName(appData.pixmapDirectory), ss);\r
+ if (appData.debugMode) {\r
+ fprintf(stderr, "(File:%s:) ", buf);\r
+ }\r
+ if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,\r
+ &xpmDarkSquare, NULL, &attr)) != 0) {\r
+ fprintf(stderr, "Error %d loading XPM file \"%s\"\n", r, buf);\r
+ exit(1);\r
+ }\r
+ }\r
+ xpmJailSquare = xpmLightSquare;\r
+ fprintf(stderr, "Done.\n");\r
+ }\r
+ XSynchronize(xDisplay, False); /* Work-around for xlib/xt\r
+ buffering bug */ \r
+}\r
+#endif /* HAVE_LIBXPM */\r
+\r
+#if HAVE_LIBXPM\r
+/* No built-in bitmaps */\r
+void CreatePieces()\r
+{\r
+ int piece, kind;\r
+ char buf[MSG_SIZ];\r
+ u_int ss = squareSize;\r
+ \r
+ XSynchronize(xDisplay, True); /* Work-around for xlib/xt\r
+ buffering bug */\r
+\r
+ for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {\r
+ for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {\r
+ sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),\r
+ ss, kind == SOLID ? 's' : 'o');\r
+ ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);\r
+ }\r
+ }\r
+ \r
+ XSynchronize(xDisplay, False); /* Work-around for xlib/xt\r
+ buffering bug */\r
+}\r
+#else\r
+/* With built-in bitmaps */\r
+void CreatePieces()\r
+{\r
+ BuiltInBits* bib = builtInBits;\r
+ int piece, kind;\r
+ char buf[MSG_SIZ];\r
+ u_int ss = squareSize;\r
+ \r
+ XSynchronize(xDisplay, True); /* Work-around for xlib/xt\r
+ buffering bug */\r
+\r
+ while (bib->squareSize != ss && bib->squareSize != 0) bib++;\r
+\r
+ for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {\r
+ for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {\r
+ sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),\r
+ ss, kind == SOLID ? 's' : 'o');\r
+ ReadBitmap(&pieceBitmap[kind][piece], buf,\r
+ bib->bits[kind][piece], ss, ss);\r
+ }\r
+ }\r
+ \r
+ XSynchronize(xDisplay, False); /* Work-around for xlib/xt\r
+ buffering bug */\r
+}\r
+#endif\r
+\r
+void ReadBitmap(pm, name, bits, wreq, hreq)\r
+ Pixmap *pm;\r
+ String name;\r
+ unsigned char bits[];\r
+ u_int wreq, hreq;\r
+{\r
+ int x_hot, y_hot;\r
+ u_int w, h;\r
+ int errcode;\r
+ char msg[MSG_SIZ], fullname[MSG_SIZ];\r
+ \r
+ if (*appData.bitmapDirectory != NULLCHAR) {\r
+ strcpy(fullname, appData.bitmapDirectory);\r
+ strcat(fullname, "/");\r
+ strcat(fullname, name);\r
+ errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,\r
+ &w, &h, pm, &x_hot, &y_hot);\r
+ if (errcode != BitmapSuccess) {\r
+ switch (errcode) {\r
+ case BitmapOpenFailed:\r
+ sprintf(msg, "Can't open bitmap file %s", fullname);\r
+ break;\r
+ case BitmapFileInvalid:\r
+ sprintf(msg, "Invalid bitmap in file %s", fullname);\r
+ break;\r
+ case BitmapNoMemory:\r
+ sprintf(msg, "Ran out of memory reading bitmap file %s",\r
+ fullname);\r
+ break;\r
+ default:\r
+ sprintf(msg, "Unknown XReadBitmapFile error %d on file %s",\r
+ errcode, fullname);\r
+ break;\r
+ }\r
+ fprintf(stderr, "%s: %s...using built-in\n",\r
+ programName, msg);\r
+ } else if (w != wreq || h != hreq) {\r
+ fprintf(stderr,\r
+ "%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n",\r
+ programName, fullname, w, h, wreq, hreq);\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+ if (bits == NULL) {\r
+#if 0\r
+ fprintf(stderr, "%s: No built-in bitmap for %s; giving up\n",\r
+ programName, name);\r
+ exit(1);\r
+#endif\r
+ ; // [HGM] bitmaps: make it non-fatal if we have no bitmap;\r
+ } else {\r
+ *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,\r
+ wreq, hreq);\r
+ }\r
+}\r
+\r
+void CreateGrid()\r
+{\r
+ int i, j;\r
+ \r
+ if (lineGap == 0) return;\r
+\r
+ /* [HR] Split this into 2 loops for non-square boards. */\r
+\r
+ for (i = 0; i < BOARD_HEIGHT + 1; i++) {\r
+ gridSegments[i].x1 = 0;\r
+ gridSegments[i].x2 =\r
+ lineGap + BOARD_WIDTH * (squareSize + lineGap);\r
+ gridSegments[i].y1 = gridSegments[i].y2\r
+ = lineGap / 2 + (i * (squareSize + lineGap));\r
+ }\r
+\r
+ for (j = 0; j < BOARD_WIDTH + 1; j++) {\r
+ gridSegments[j + i].y1 = 0;\r
+ gridSegments[j + i].y2 =\r
+ lineGap + BOARD_HEIGHT * (squareSize + lineGap);\r
+ gridSegments[j + i].x1 = gridSegments[j + i].x2\r
+ = lineGap / 2 + (j * (squareSize + lineGap));\r
+ }\r
+}\r
+\r
+static void MenuBarSelect(w, addr, index)\r
+ Widget w;\r
+ caddr_t addr;\r
+ caddr_t index;\r
+{\r
+ XtActionProc proc = (XtActionProc) addr;\r
+\r
+ (proc)(NULL, NULL, NULL, NULL);\r
+}\r
+\r
+void CreateMenuBarPopup(parent, name, mb)\r
+ Widget parent;\r
+ String name;\r
+ Menu *mb;\r
+{\r
+ int j;\r
+ Widget menu, entry;\r
+ MenuItem *mi;\r
+ Arg args[16];\r
+\r
+ menu = XtCreatePopupShell(name, simpleMenuWidgetClass,\r
+ parent, NULL, 0);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNleftMargin, 20); j++;\r
+ XtSetArg(args[j], XtNrightMargin, 20); j++;\r
+ mi = mb->mi;\r
+ while (mi->string != NULL) {\r
+ if (strcmp(mi->string, "----") == 0) {\r
+ entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,\r
+ menu, args, j);\r
+ } else {\r
+ entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,\r
+ menu, args, j);\r
+ XtAddCallback(entry, XtNcallback,\r
+ (XtCallbackProc) MenuBarSelect,\r
+ (caddr_t) mi->proc);\r
+ }\r
+ mi++;\r
+ }\r
+} \r
+\r
+Widget CreateMenuBar(mb)\r
+ Menu *mb;\r
+{\r
+ int j;\r
+ Widget anchor, menuBar;\r
+ Arg args[16];\r
+ char menuName[MSG_SIZ];\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;\r
+ XtSetArg(args[j], XtNvSpace, 0); j++;\r
+ XtSetArg(args[j], XtNborderWidth, 0); j++;\r
+ menuBar = XtCreateWidget("menuBar", boxWidgetClass,\r
+ formWidget, args, j);\r
+\r
+ while (mb->name != NULL) {\r
+ strcpy(menuName, "menu");\r
+ strcat(menuName, mb->name);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;\r
+ if (tinyLayout) {\r
+ char shortName[2];\r
+ shortName[0] = mb->name[0];\r
+ shortName[1] = NULLCHAR;\r
+ XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;\r
+ }\r
+ XtSetArg(args[j], XtNborderWidth, 0); j++;\r
+ anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,\r
+ menuBar, args, j);\r
+ CreateMenuBarPopup(menuBar, menuName, mb);\r
+ mb++;\r
+ }\r
+ return menuBar;\r
+}\r
+\r
+Widget CreateButtonBar(mi)\r
+ MenuItem *mi;\r
+{\r
+ int j;\r
+ Widget button, buttonBar;\r
+ Arg args[16];\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;\r
+ if (tinyLayout) {\r
+ XtSetArg(args[j], XtNhSpace, 0); j++;\r
+ }\r
+ XtSetArg(args[j], XtNborderWidth, 0); j++;\r
+ XtSetArg(args[j], XtNvSpace, 0); j++;\r
+ buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,\r
+ formWidget, args, j);\r
+\r
+ while (mi->string != NULL) {\r
+ j = 0;\r
+ if (tinyLayout) {\r
+ XtSetArg(args[j], XtNinternalWidth, 2); j++;\r
+ XtSetArg(args[j], XtNborderWidth, 0); j++;\r
+ }\r
+ button = XtCreateManagedWidget(mi->string, commandWidgetClass,\r
+ buttonBar, args, j);\r
+ XtAddCallback(button, XtNcallback,\r
+ (XtCallbackProc) MenuBarSelect,\r
+ (caddr_t) mi->proc);\r
+ mi++;\r
+ }\r
+ return buttonBar;\r
+} \r
+\r
+Widget\r
+CreatePieceMenu(name, color)\r
+ char *name;\r
+ int color;\r
+{\r
+ int i;\r
+ Widget entry, menu;\r
+ Arg args[16];\r
+ ChessSquare selection;\r
+\r
+ menu = XtCreatePopupShell(name, simpleMenuWidgetClass,\r
+ boardWidget, args, 0);\r
+ \r
+ for (i = 0; i < PIECE_MENU_SIZE; i++) {\r
+ String item = pieceMenuStrings[color][i];\r
+ \r
+ if (strcmp(item, "----") == 0) {\r
+ entry = XtCreateManagedWidget(item, smeLineObjectClass,\r
+ menu, NULL, 0);\r
+ } else {\r
+ entry = XtCreateManagedWidget(item, smeBSBObjectClass,\r
+ menu, NULL, 0);\r
+ selection = pieceMenuTranslation[color][i];\r
+ XtAddCallback(entry, XtNcallback,\r
+ (XtCallbackProc) PieceMenuSelect,\r
+ (caddr_t) selection);\r
+ if (selection == WhitePawn || selection == BlackPawn) {\r
+ XtSetArg(args[0], XtNpopupOnEntry, entry);\r
+ XtSetValues(menu, args, 1);\r
+ }\r
+ }\r
+ }\r
+ return menu;\r
+}\r
+\r
+void\r
+CreatePieceMenus()\r
+{\r
+ int i;\r
+ Widget entry;\r
+ Arg args[16];\r
+ ChessSquare selection;\r
+\r
+ whitePieceMenu = CreatePieceMenu("menuW", 0);\r
+ blackPieceMenu = CreatePieceMenu("menuB", 1);\r
+ \r
+ XtRegisterGrabAction(PieceMenuPopup, True,\r
+ (unsigned)(ButtonPressMask|ButtonReleaseMask),\r
+ GrabModeAsync, GrabModeAsync);\r
+\r
+ XtSetArg(args[0], XtNlabel, "Drop");\r
+ dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,\r
+ boardWidget, args, 1);\r
+ for (i = 0; i < DROP_MENU_SIZE; i++) {\r
+ String item = dropMenuStrings[i];\r
+ \r
+ if (strcmp(item, "----") == 0) {\r
+ entry = XtCreateManagedWidget(item, smeLineObjectClass,\r
+ dropMenu, NULL, 0);\r
+ } else {\r
+ entry = XtCreateManagedWidget(item, smeBSBObjectClass,\r
+ dropMenu, NULL, 0);\r
+ selection = dropMenuTranslation[i];\r
+ XtAddCallback(entry, XtNcallback,\r
+ (XtCallbackProc) DropMenuSelect,\r
+ (caddr_t) selection);\r
+ }\r
+ }\r
+} \r
+\r
+void SetupDropMenu()\r
+{\r
+ int i, j, count;\r
+ char label[32];\r
+ Arg args[16];\r
+ Widget entry;\r
+ char* p;\r
+\r
+ for (i=0; i<sizeof(dmEnables)/sizeof(DropMenuEnables); i++) {\r
+ entry = XtNameToWidget(dropMenu, dmEnables[i].widget);\r
+ p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,\r
+ dmEnables[i].piece);\r
+ XtSetSensitive(entry, p != NULL || !appData.testLegality\r
+ /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse\r
+ && !appData.icsActive));\r
+ count = 0;\r
+ while (p && *p++ == dmEnables[i].piece) count++;\r
+ sprintf(label, "%s %d", dmEnables[i].widget, count);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNlabel, label); j++;\r
+ XtSetValues(entry, args, j);\r
+ }\r
+}\r
+\r
+void PieceMenuPopup(w, event, params, num_params)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *params;\r
+ Cardinal *num_params;\r
+{\r
+ String whichMenu;\r
+ if (event->type != ButtonPress) return;\r
+ if (errorUp) ErrorPopDown();\r
+ switch (gameMode) {\r
+ case EditPosition:\r
+ case IcsExamining:\r
+ whichMenu = params[0];\r
+ break;\r
+ case IcsPlayingWhite:\r
+ case IcsPlayingBlack:\r
+ case EditGame:\r
+ case MachinePlaysWhite:\r
+ case MachinePlaysBlack:\r
+ if (appData.testLegality &&\r
+ gameInfo.variant != VariantBughouse &&\r
+ gameInfo.variant != VariantCrazyhouse) return;\r
+ SetupDropMenu();\r
+ whichMenu = "menuD";\r
+ break;\r
+ default:\r
+ return;\r
+ }\r
+ \r
+ if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||\r
+ ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {\r
+ pmFromX = pmFromY = -1;\r
+ return;\r
+ }\r
+ if (flipView)\r
+ pmFromX = BOARD_WIDTH - 1 - pmFromX;\r
+ else\r
+ pmFromY = BOARD_HEIGHT - 1 - pmFromY;\r
+ \r
+ XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));\r
+}\r
+\r
+static void PieceMenuSelect(w, piece, junk)\r
+ Widget w;\r
+ ChessSquare piece;\r
+ caddr_t junk;\r
+{\r
+ if (pmFromX < 0 || pmFromY < 0) return;\r
+ EditPositionMenuEvent(piece, pmFromX, pmFromY);\r
+}\r
+\r
+static void DropMenuSelect(w, piece, junk)\r
+ Widget w;\r
+ ChessSquare piece;\r
+ caddr_t junk;\r
+{\r
+ if (pmFromX < 0 || pmFromY < 0) return;\r
+ DropMenuEvent(piece, pmFromX, pmFromY);\r
+}\r
+\r
+void WhiteClock(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (gameMode == EditPosition || gameMode == IcsExamining) {\r
+ SetWhiteToPlayEvent();\r
+ } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {\r
+ CallFlagEvent();\r
+ }\r
+}\r
+\r
+void BlackClock(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (gameMode == EditPosition || gameMode == IcsExamining) {\r
+ SetBlackToPlayEvent();\r
+ } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {\r
+ CallFlagEvent();\r
+ }\r
+}\r
+\r
+\r
+/*\r
+ * If the user selects on a border boundary, return -1; if off the board,\r
+ * return -2. Otherwise map the event coordinate to the square.\r
+ */\r
+int EventToSquare(x, limit)\r
+ int x;\r
+{\r
+ if (x <= 0) \r
+ return -2;\r
+ if (x < lineGap)\r
+ return -1;\r
+ x -= lineGap;\r
+ if ((x % (squareSize + lineGap)) >= squareSize)\r
+ return -1;\r
+ x /= (squareSize + lineGap);\r
+ if (x >= limit)\r
+ return -2;\r
+ return x;\r
+}\r
+\r
+static void do_flash_delay(msec)\r
+ unsigned long msec;\r
+{\r
+ TimeDelay(msec);\r
+}\r
+\r
+static void drawHighlight(file, rank, gc)\r
+ int file, rank;\r
+ GC gc;\r
+{\r
+ int x, y;\r
+\r
+ if (lineGap == 0 || appData.blindfold) return;\r
+ \r
+ if (flipView) {\r
+ x = lineGap/2 + ((BOARD_WIDTH-1)-file) * \r
+ (squareSize + lineGap);\r
+ y = lineGap/2 + rank * (squareSize + lineGap);\r
+ } else {\r
+ x = lineGap/2 + file * (squareSize + lineGap);\r
+ y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) * \r
+ (squareSize + lineGap);\r
+ }\r
+ \r
+ XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,\r
+ squareSize+lineGap, squareSize+lineGap);\r
+}\r
+\r
+int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;\r
+int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1;\r
+\r
+void\r
+SetHighlights(fromX, fromY, toX, toY)\r
+ int fromX, fromY, toX, toY;\r
+{\r
+ if (hi1X != fromX || hi1Y != fromY) {\r
+ if (hi1X >= 0 && hi1Y >= 0) {\r
+ drawHighlight(hi1X, hi1Y, lineGC);\r
+ }\r
+ if (fromX >= 0 && fromY >= 0) {\r
+ drawHighlight(fromX, fromY, highlineGC);\r
+ }\r
+ }\r
+ if (hi2X != toX || hi2Y != toY) {\r
+ if (hi2X >= 0 && hi2Y >= 0) {\r
+ drawHighlight(hi2X, hi2Y, lineGC);\r
+ }\r
+ if (toX >= 0 && toY >= 0) {\r
+ drawHighlight(toX, toY, highlineGC);\r
+ }\r
+ }\r
+ hi1X = fromX;\r
+ hi1Y = fromY;\r
+ hi2X = toX;\r
+ hi2Y = toY;\r
+}\r
+\r
+void\r
+ClearHighlights()\r
+{\r
+ SetHighlights(-1, -1, -1, -1);\r
+}\r
+\r
+\r
+void\r
+SetPremoveHighlights(fromX, fromY, toX, toY)\r
+ int fromX, fromY, toX, toY;\r
+{\r
+ if (pm1X != fromX || pm1Y != fromY) {\r
+ if (pm1X >= 0 && pm1Y >= 0) {\r
+ drawHighlight(pm1X, pm1Y, lineGC);\r
+ }\r
+ if (fromX >= 0 && fromY >= 0) {\r
+ drawHighlight(fromX, fromY, prelineGC);\r
+ }\r
+ }\r
+ if (pm2X != toX || pm2Y != toY) {\r
+ if (pm2X >= 0 && pm2Y >= 0) {\r
+ drawHighlight(pm2X, pm2Y, lineGC);\r
+ }\r
+ if (toX >= 0 && toY >= 0) {\r
+ drawHighlight(toX, toY, prelineGC);\r
+ }\r
+ }\r
+ pm1X = fromX;\r
+ pm1Y = fromY;\r
+ pm2X = toX;\r
+ pm2Y = toY;\r
+}\r
+\r
+void\r
+ClearPremoveHighlights()\r
+{\r
+ SetPremoveHighlights(-1, -1, -1, -1);\r
+}\r
+\r
+static void BlankSquare(x, y, color, piece, dest)\r
+ int x, y, color;\r
+ ChessSquare piece;\r
+ Drawable dest;\r
+{\r
+ if (useImages && useImageSqs) {\r
+ Pixmap pm;\r
+ switch (color) {\r
+ case 1: /* light */\r
+ pm = xpmLightSquare;\r
+ break;\r
+ case 0: /* dark */\r
+ pm = xpmDarkSquare;\r
+ break;\r
+ case 2: /* neutral */\r
+ default:\r
+ pm = xpmJailSquare;\r
+ break;\r
+ }\r
+ XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y);\r
+ } else {\r
+ GC gc;\r
+ switch (color) {\r
+ case 1: /* light */\r
+ gc = lightSquareGC;\r
+ break;\r
+ case 0: /* dark */\r
+ gc = darkSquareGC;\r
+ break;\r
+ case 2: /* neutral */\r
+ default:\r
+ gc = jailSquareGC;\r
+ break;\r
+ }\r
+ XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize);\r
+ }\r
+}\r
+\r
+/*\r
+ I split out the routines to draw a piece so that I could\r
+ make a generic flash routine.\r
+*/\r
+static void monoDrawPiece_1bit(piece, square_color, x, y, dest)\r
+ ChessSquare piece;\r
+ int square_color, x, y;\r
+ Drawable dest;\r
+{\r
+ /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */\r
+ switch (square_color) {\r
+ case 1: /* light */\r
+ case 2: /* neutral */\r
+ default:\r
+ XCopyArea(xDisplay, (int) piece < (int) BlackPawn\r
+ ? *pieceToOutline(piece)\r
+ : *pieceToSolid(piece),\r
+ dest, bwPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y);\r
+ break;\r
+ case 0: /* dark */\r
+ XCopyArea(xDisplay, (int) piece < (int) BlackPawn\r
+ ? *pieceToSolid(piece)\r
+ : *pieceToOutline(piece),\r
+ dest, wbPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y);\r
+ break;\r
+ }\r
+}\r
+\r
+static void monoDrawPiece(piece, square_color, x, y, dest)\r
+ ChessSquare piece;\r
+ int square_color, x, y;\r
+ Drawable dest;\r
+{\r
+ switch (square_color) {\r
+ case 1: /* light */\r
+ case 2: /* neutral */\r
+ default:\r
+ XCopyPlane(xDisplay, (int) piece < (int) BlackPawn\r
+ ? *pieceToOutline(piece)\r
+ : *pieceToSolid(piece),\r
+ dest, bwPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y, 1);\r
+ break;\r
+ case 0: /* dark */\r
+ XCopyPlane(xDisplay, (int) piece < (int) BlackPawn\r
+ ? *pieceToSolid(piece)\r
+ : *pieceToOutline(piece),\r
+ dest, wbPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y, 1);\r
+ break;\r
+ }\r
+}\r
+\r
+static void colorDrawPiece(piece, square_color, x, y, dest)\r
+ ChessSquare piece;\r
+ int square_color, x, y;\r
+ Drawable dest;\r
+{\r
+ if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;\r
+ switch (square_color) {\r
+ case 1: /* light */\r
+ XCopyPlane(xDisplay, *pieceToSolid(piece),\r
+ dest, (int) piece < (int) BlackPawn\r
+ ? wlPieceGC : blPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y, 1);\r
+ break;\r
+ case 0: /* dark */\r
+ XCopyPlane(xDisplay, *pieceToSolid(piece),\r
+ dest, (int) piece < (int) BlackPawn\r
+ ? wdPieceGC : bdPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y, 1);\r
+ break;\r
+ case 2: /* neutral */\r
+ default:\r
+ XCopyPlane(xDisplay, *pieceToSolid(piece),\r
+ dest, (int) piece < (int) BlackPawn\r
+ ? wjPieceGC : bjPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y, 1);\r
+ break;\r
+ }\r
+}\r
+\r
+static void colorDrawPieceImage(piece, square_color, x, y, dest)\r
+ ChessSquare piece;\r
+ int square_color, x, y;\r
+ Drawable dest;\r
+{\r
+ int kind;\r
+\r
+ switch (square_color) {\r
+ case 1: /* light */\r
+ case 2: /* neutral */\r
+ default:\r
+ if ((int)piece < (int) BlackPawn) {\r
+ kind = 0;\r
+ } else {\r
+ kind = 2;\r
+ piece -= BlackPawn;\r
+ }\r
+ break;\r
+ case 0: /* dark */\r
+ if ((int)piece < (int) BlackPawn) {\r
+ kind = 1;\r
+ } else {\r
+ kind = 3;\r
+ piece -= BlackPawn;\r
+ }\r
+ break;\r
+ }\r
+ XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],\r
+ dest, wlPieceGC, 0, 0,\r
+ squareSize, squareSize, x, y); \r
+}\r
+\r
+typedef void (*DrawFunc)();\r
+\r
+DrawFunc ChooseDrawFunc()\r
+{\r
+ if (appData.monoMode) {\r
+ if (DefaultDepth(xDisplay, xScreen) == 1) {\r
+ return monoDrawPiece_1bit;\r
+ } else {\r
+ return monoDrawPiece;\r
+ }\r
+ } else {\r
+ if (useImages)\r
+ return colorDrawPieceImage;\r
+ else\r
+ return colorDrawPiece;\r
+ }\r
+}\r
+\r
+/* [HR] determine square color depending on chess variant. */\r
+static int SquareColor(row, column)\r
+ int row, column;\r
+{\r
+ int square_color;\r
+\r
+ if (gameInfo.variant == VariantXiangqi) {\r
+ if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {\r
+ square_color = 0;\r
+ } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {\r
+ square_color = 1;\r
+ } else if (row <= 4) {\r
+ square_color = 1;\r
+ } else {\r
+ square_color = 0;\r
+ }\r
+ } else {\r
+ square_color = ((column + row) % 2) == 1;\r
+ }\r
+\r
+ /* [hgm] holdings: next line makes all holdings squares light */\r
+ if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 0;\r
+ \r
+ return square_color;\r
+}\r
+\r
+void DrawSquare(row, column, piece, do_flash)\r
+ int row, column, do_flash;\r
+ ChessSquare piece;\r
+{\r
+ int square_color, x, y, direction, font_ascent, font_descent;\r
+ int i;\r
+ char string[2];\r
+ XCharStruct overall;\r
+ DrawFunc drawfunc;\r
+ int flash_delay;\r
+\r
+ /* Calculate delay in milliseconds (2-delays per complete flash) */\r
+ flash_delay = 500 / appData.flashRate;\r
+ \r
+ if (flipView) {\r
+ x = lineGap + ((BOARD_WIDTH-1)-column) * \r
+ (squareSize + lineGap);\r
+ y = lineGap + row * (squareSize + lineGap);\r
+ } else {\r
+ x = lineGap + column * (squareSize + lineGap);\r
+ y = lineGap + ((BOARD_HEIGHT-1)-row) * \r
+ (squareSize + lineGap);\r
+ }\r
+ \r
+ square_color = SquareColor(row, column);\r
+ \r
+ if ( // [HGM] holdings: next 5 lines blank out area between board and holdings\r
+ column == BOARD_LEFT-1 || column == BOARD_RGHT\r
+ || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)\r
+ || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {\r
+ BlankSquare(x, y, 2, EmptySquare, xBoardWindow);\r
+ } else {\r
+ if (piece == EmptySquare || appData.blindfold) {\r
+ BlankSquare(x, y, square_color, piece, xBoardWindow);\r
+ } else {\r
+ drawfunc = ChooseDrawFunc();\r
+ if (do_flash && appData.flashCount > 0) {\r
+ for (i=0; i<appData.flashCount; ++i) {\r
+\r
+ drawfunc(piece, square_color, x, y, xBoardWindow);\r
+ XSync(xDisplay, False);\r
+ do_flash_delay(flash_delay);\r
+\r
+ BlankSquare(x, y, square_color, piece, xBoardWindow);\r
+ XSync(xDisplay, False);\r
+ do_flash_delay(flash_delay);\r
+ }\r
+ }\r
+ drawfunc(piece, square_color, x, y, xBoardWindow);\r
+ }\r
+ }\r
+ \r
+ string[1] = NULLCHAR;\r
+ if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)) {\r
+ string[0] = 'a' + column;\r
+ XTextExtents(coordFontStruct, string, 1, &direction, \r
+ &font_ascent, &font_descent, &overall);\r
+ if (appData.monoMode) {\r
+ XDrawImageString(xDisplay, xBoardWindow, coordGC,\r
+ x + squareSize - overall.width - 2, \r
+ y + squareSize - font_descent - 1, string, 1);\r
+ } else {\r
+ XDrawString(xDisplay, xBoardWindow, coordGC,\r
+ x + squareSize - overall.width - 2, \r
+ y + squareSize - font_descent - 1, string, 1);\r
+ }\r
+ }\r
+ if (appData.showCoords && column == (flipView ? BOARD_WIDTH-1 : 0)) {\r
+ string[0] = ONE + row;\r
+ XTextExtents(coordFontStruct, string, 1, &direction, \r
+ &font_ascent, &font_descent, &overall);\r
+ if (appData.monoMode) {\r
+ XDrawImageString(xDisplay, xBoardWindow, coordGC,\r
+ x + 2, y + font_ascent + 1, string, 1);\r
+ } else {\r
+ XDrawString(xDisplay, xBoardWindow, coordGC,\r
+ x + 2, y + font_ascent + 1, string, 1);\r
+ } \r
+ } \r
+}\r
+\r
+\r
+/* Why is this needed on some versions of X? */\r
+void EventProc(widget, unused, event)\r
+ Widget widget;\r
+ caddr_t unused;\r
+ XEvent *event;\r
+{\r
+ if (!XtIsRealized(widget))\r
+ return;\r
+\r
+ switch (event->type) {\r
+ case Expose:\r
+ if (event->xexpose.count > 0) return; /* no clipping is done */\r
+ XDrawPosition(widget, True, NULL);\r
+ break;\r
+ default:\r
+ return;\r
+ }\r
+}\r
+/* end why */\r
+\r
+void DrawPosition(fullRedraw, board)\r
+ /*Boolean*/int fullRedraw;\r
+ Board board;\r
+{\r
+ XDrawPosition(boardWidget, fullRedraw, board);\r
+}\r
+\r
+/* Returns 1 if there are "too many" differences between b1 and b2\r
+ (i.e. more than 1 move was made) */\r
+static int too_many_diffs(b1, b2)\r
+ Board b1, b2;\r
+{\r
+ int i, j;\r
+ int c = 0;\r
+ \r
+ for (i=0; i<BOARD_HEIGHT; ++i) {\r
+ for (j=0; j<BOARD_WIDTH; ++j) {\r
+ if (b1[i][j] != b2[i][j]) {\r
+ if (++c > 4) /* Castling causes 4 diffs */\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/* Matrix describing castling maneuvers */\r
+/* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */\r
+static int castling_matrix[4][5] = {\r
+ { 0, 0, 4, 3, 2 }, /* 0-0-0, white */\r
+ { 0, 7, 4, 5, 6 }, /* 0-0, white */\r
+ { 7, 0, 4, 3, 2 }, /* 0-0-0, black */\r
+ { 7, 7, 4, 5, 6 } /* 0-0, black */\r
+};\r
+\r
+/* Checks whether castling occurred. If it did, *rrow and *rcol\r
+ are set to the destination (row,col) of the rook that moved.\r
+ \r
+ Returns 1 if castling occurred, 0 if not.\r
+ \r
+ Note: Only handles a max of 1 castling move, so be sure\r
+ to call too_many_diffs() first.\r
+ */\r
+static int check_castle_draw(newb, oldb, rrow, rcol)\r
+ Board newb, oldb;\r
+ int *rrow, *rcol;\r
+{\r
+ int i, *r, j;\r
+ int match;\r
+\r
+ /* For each type of castling... */\r
+ for (i=0; i<4; ++i) {\r
+ r = castling_matrix[i];\r
+\r
+ /* Check the 4 squares involved in the castling move */\r
+ match = 0;\r
+ for (j=1; j<=4; ++j) {\r
+ if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) {\r
+ match = 1;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!match) {\r
+ /* All 4 changed, so it must be a castling move */\r
+ *rrow = r[0];\r
+ *rcol = r[3];\r
+ return 1;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int damage[BOARD_SIZE][BOARD_SIZE];\r
+\r
+/*\r
+ * event handler for redrawing the board\r
+ */\r
+void XDrawPosition(w, repaint, board)\r
+ Widget w;\r
+ /*Boolean*/int repaint;\r
+ Board board;\r
+{\r
+ int i, j, do_flash;\r
+ static int lastFlipView = 0;\r
+ static int lastBoardValid = 0;\r
+ static Board lastBoard;\r
+ Arg args[16];\r
+ int rrow, rcol;\r
+ \r
+ if (board == NULL) {\r
+ if (!lastBoardValid) return;\r
+ board = lastBoard;\r
+ }\r
+ if (!lastBoardValid || lastFlipView != flipView) {\r
+ XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),\r
+ args, 1);\r
+ }\r
+\r
+ /*\r
+ * It would be simpler to clear the window with XClearWindow()\r
+ * but this causes a very distracting flicker.\r
+ */\r
+ \r
+ if (!repaint && lastBoardValid && lastFlipView == flipView) {\r
+\r
+ /* If too much changes (begin observing new game, etc.), don't\r
+ do flashing */\r
+ do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;\r
+\r
+ /* Special check for castling so we don't flash both the king\r
+ and the rook (just flash the king). */\r
+ if (do_flash) {\r
+ if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {\r
+ /* Draw rook with NO flashing. King will be drawn flashing later */\r
+ DrawSquare(rrow, rcol, board[rrow][rcol], 0);\r
+ lastBoard[rrow][rcol] = board[rrow][rcol];\r
+ }\r
+ }\r
+\r
+ /* First pass -- Draw (newly) empty squares and repair damage. \r
+ This prevents you from having a piece show up twice while it \r
+ is flashing on its new square */\r
+ for (i = 0; i < BOARD_HEIGHT; i++)\r
+ for (j = 0; j < BOARD_WIDTH; j++)\r
+ if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)\r
+ || damage[i][j]) {\r
+ DrawSquare(i, j, board[i][j], 0);\r
+ damage[i][j] = False;\r
+ }\r
+\r
+ /* Second pass -- Draw piece(s) in new position and flash them */\r
+ for (i = 0; i < BOARD_HEIGHT; i++)\r
+ for (j = 0; j < BOARD_WIDTH; j++)\r
+ if (board[i][j] != lastBoard[i][j]) {\r
+ DrawSquare(i, j, board[i][j], do_flash); \r
+ }\r
+ } else {\r
+ if (lineGap > 0)\r
+ XDrawSegments(xDisplay, xBoardWindow, lineGC,\r
+ gridSegments, (BOARD_SIZE + 1) * 2);\r
+ \r
+ for (i = 0; i < BOARD_HEIGHT; i++)\r
+ for (j = 0; j < BOARD_WIDTH; j++) {\r
+ DrawSquare(i, j, board[i][j], 0);\r
+ damage[i][j] = False;\r
+ }\r
+ }\r
+\r
+ CopyBoard(lastBoard, board);\r
+ lastBoardValid = 1;\r
+ lastFlipView = flipView;\r
+\r
+ /* Draw highlights */\r
+ if (pm1X >= 0 && pm1Y >= 0) {\r
+ drawHighlight(pm1X, pm1Y, prelineGC);\r
+ }\r
+ if (pm2X >= 0 && pm2Y >= 0) {\r
+ drawHighlight(pm2X, pm2Y, prelineGC);\r
+ }\r
+ if (hi1X >= 0 && hi1Y >= 0) {\r
+ drawHighlight(hi1X, hi1Y, highlineGC);\r
+ }\r
+ if (hi2X >= 0 && hi2Y >= 0) {\r
+ drawHighlight(hi2X, hi2Y, highlineGC);\r
+ }\r
+\r
+ /* If piece being dragged around board, must redraw that too */\r
+ DrawDragPiece();\r
+\r
+ XSync(xDisplay, False);\r
+}\r
+\r
+\r
+/*\r
+ * event handler for redrawing the board\r
+ */\r
+void DrawPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ XDrawPosition(w, True, NULL);\r
+}\r
+\r
+\r
+/*\r
+ * event handler for parsing user moves\r
+ */\r
+// [HGM] This routine will need quite some reworking. Although the backend still supports the old\r
+// way of doing things, by calling UserMoveEvent() to test the legality of the move and then perform\r
+// it at the end, and doing all kind of preliminary tests here (e.g. to weed out self-captures), it\r
+// should be made to use the new way, of calling UserMoveTest early to determine the legality of the\r
+// move, (which will weed out the illegal selfcaptures and moves into the holdings, and flag promotions),\r
+// and at the end FinishMove() to perform the move after optional promotion popups.\r
+// For now I patched it to allow self-capture with King, and suppress clicks between board and holdings.\r
+void HandleUserMove(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ int x, y;\r
+ Boolean saveAnimate;\r
+ static int second = 0;\r
+ \r
+ if (w != boardWidget || errorExitStatus != -1) return;\r
+\r
+ if (event->type == ButtonPress) ErrorPopDown();\r
+\r
+ if (promotionUp) {\r
+ if (event->type == ButtonPress) {\r
+ XtPopdown(promotionShell);\r
+ XtDestroyWidget(promotionShell);\r
+ promotionUp = False;\r
+ ClearHighlights();\r
+ fromX = fromY = -1;\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+ \r
+ x = EventToSquare(event->xbutton.x, BOARD_WIDTH);\r
+ y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);\r
+ if (!flipView && y >= 0) {\r
+ y = BOARD_HEIGHT - 1 - y;\r
+ }\r
+ if (flipView && x >= 0) {\r
+ x = BOARD_WIDTH - 1 - x;\r
+ }\r
+\r
+ /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */\r
+ if(event->type == ButtonPress\r
+ && ( x == BOARD_LEFT-1 || x == BOARD_RGHT\r
+ || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize\r
+ || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) )\r
+ return;\r
+\r
+ if (fromX == -1) {\r
+ if (event->type == ButtonPress) {\r
+ /* First square */ \r
+ if (OKToStartUserMove(x, y)) {\r
+ fromX = x;\r
+ fromY = y;\r
+ second = 0;\r
+ DragPieceBegin(event->xbutton.x, event->xbutton.y);\r
+ if (appData.highlightDragging) {\r
+ SetHighlights(x, y, -1, -1);\r
+ }\r
+ } \r
+ }\r
+ return;\r
+ }\r
+\r
+ /* fromX != -1 */\r
+ if (event->type == ButtonPress && gameMode != EditPosition &&\r
+ x >= 0 && y >= 0) {\r
+ ChessSquare fromP;\r
+ ChessSquare toP;\r
+\r
+ /* Check if clicking again on the same color piece */\r
+ fromP = boards[currentMove][fromY][fromX];\r
+ toP = boards[currentMove][y][x];\r
+ if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.\r
+ WhitePawn <= toP && toP <= WhiteKing) || // For now I made it less critical by exempting King\r
+ (BlackPawn <= fromP && fromP < BlackKing && // moves, to not interfere with FRC castlings.\r
+ BlackPawn <= toP && toP <= BlackKing)) {\r
+ /* Clicked again on same color piece -- changed his mind */\r
+ second = (x == fromX && y == fromY);\r
+ if (appData.highlightDragging) {\r
+ SetHighlights(x, y, -1, -1);\r
+ } else {\r
+ ClearHighlights();\r
+ }\r
+ if (OKToStartUserMove(x, y)) {\r
+ fromX = x;\r
+ fromY = y;\r
+ DragPieceBegin(event->xbutton.x, event->xbutton.y);\r
+ }\r
+ return;\r
+ }\r
+ }\r
+\r
+ if (event->type == ButtonRelease && x == fromX && y == fromY) {\r
+ DragPieceEnd(event->xbutton.x, event->xbutton.y);\r
+ if (appData.animateDragging) {\r
+ /* Undo animation damage if any */\r
+ DrawPosition(FALSE, NULL);\r
+ }\r
+ if (second) {\r
+ /* Second up/down in same square; just abort move */\r
+ second = 0;\r
+ fromX = fromY = -1;\r
+ ClearHighlights();\r
+ gotPremove = 0;\r
+ ClearPremoveHighlights();\r
+ } else {\r
+ /* First upclick in same square; start click-click mode */\r
+ SetHighlights(x, y, -1, -1);\r
+ }\r
+ return;\r
+ } \r
+\r
+ /* Completed move */\r
+ toX = x;\r
+ toY = y;\r
+ saveAnimate = appData.animate;\r
+ if (event->type == ButtonPress) {\r
+ /* Finish clickclick move */\r
+ if (appData.animate || appData.highlightLastMove) {\r
+ SetHighlights(fromX, fromY, toX, toY);\r
+ } else {\r
+ ClearHighlights();\r
+ }\r
+ } else {\r
+ /* Finish drag move */\r
+ if (appData.highlightLastMove) {\r
+ SetHighlights(fromX, fromY, toX, toY);\r
+ } else {\r
+ ClearHighlights();\r
+ }\r
+ DragPieceEnd(event->xbutton.x, event->xbutton.y);\r
+ /* Don't animate move and drag both */\r
+ appData.animate = FALSE;\r
+ }\r
+ if (IsPromotion(fromX, fromY, toX, toY)) {\r
+ if (appData.alwaysPromoteToQueen) {\r
+ UserMoveEvent(fromX, fromY, toX, toY, 'q');\r
+ if (!appData.highlightLastMove || gotPremove) ClearHighlights();\r
+ if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
+ fromX = fromY = -1;\r
+ } else {\r
+ SetHighlights(fromX, fromY, toX, toY);\r
+ PromotionPopUp();\r
+ }\r
+ } else {\r
+ UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);\r
+ if (!appData.highlightLastMove || gotPremove) ClearHighlights();\r
+ if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
+ fromX = fromY = -1;\r
+ }\r
+ appData.animate = saveAnimate;\r
+ if (appData.animate || appData.animateDragging) {\r
+ /* Undo animation damage if needed */\r
+ DrawPosition(FALSE, NULL);\r
+ }\r
+}\r
+\r
+void AnimateUserMove (Widget w, XEvent * event,\r
+ String * params, Cardinal * nParams)\r
+{\r
+ DragPieceMove(event->xmotion.x, event->xmotion.y);\r
+}\r
+\r
+Widget CommentCreate(name, text, mutable, callback, lines)\r
+ char *name, *text;\r
+ int /*Boolean*/ mutable;\r
+ XtCallbackProc callback;\r
+ int lines;\r
+{\r
+ Arg args[16];\r
+ Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;\r
+ Dimension bw_width;\r
+ int j;\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNwidth, &bw_width); j++;\r
+ XtGetValues(boardWidget, args, j);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNresizable, True); j++;\r
+#if TOPLEVEL\r
+ shell =\r
+ XtCreatePopupShell(name, topLevelShellWidgetClass,\r
+ shellWidget, args, j);\r
+#else\r
+ shell =\r
+ XtCreatePopupShell(name, transientShellWidgetClass,\r
+ shellWidget, args, j);\r
+#endif\r
+ layout =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, shell,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ form =\r
+ XtCreateManagedWidget("form", formWidgetClass, layout,\r
+ formArgs, XtNumber(formArgs));\r
+\r
+ j = 0;\r
+ if (mutable) {\r
+ XtSetArg(args[j], XtNeditType, XawtextEdit); j++;\r
+ XtSetArg(args[j], XtNuseStringInPlace, False); j++;\r
+ }\r
+ XtSetArg(args[j], XtNstring, text); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainTop); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainRight); j++;\r
+ XtSetArg(args[j], XtNresizable, True); j++;\r
+ XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/\r
+#if 0\r
+ XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;\r
+#else\r
+ /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */\r
+ XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;\r
+#endif\r
+ XtSetArg(args[j], XtNautoFill, True); j++;\r
+ XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;\r
+ edit =\r
+ XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);\r
+\r
+ if (mutable) {\r
+ j = 0;\r
+ XtSetArg(args[j], XtNfromVert, edit); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainLeft); j++;\r
+ b_ok =\r
+ XtCreateManagedWidget("ok", commandWidgetClass, form, args, j);\r
+ XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNfromVert, edit); j++;\r
+ XtSetArg(args[j], XtNfromHoriz, b_ok); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainLeft); j++;\r
+ b_cancel =\r
+ XtCreateManagedWidget("cancel", commandWidgetClass, form, args, j);\r
+ XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNfromVert, edit); j++;\r
+ XtSetArg(args[j], XtNfromHoriz, b_cancel); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainLeft); j++;\r
+ b_clear =\r
+ XtCreateManagedWidget("clear", commandWidgetClass, form, args, j);\r
+ XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);\r
+ } else {\r
+ j = 0;\r
+ XtSetArg(args[j], XtNfromVert, edit); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainLeft); j++;\r
+ b_close =\r
+ XtCreateManagedWidget("close", commandWidgetClass, form, args, j);\r
+ XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNfromVert, edit); j++;\r
+ XtSetArg(args[j], XtNfromHoriz, b_close); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainLeft); j++;\r
+ b_edit =\r
+ XtCreateManagedWidget("edit", commandWidgetClass, form, args, j);\r
+ XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);\r
+ }\r
+\r
+ XtRealizeWidget(shell);\r
+\r
+ if (commentX == -1) {\r
+ int xx, yy;\r
+ Window junk;\r
+ Dimension pw_height;\r
+ Dimension ew_height;\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNheight, &ew_height); j++;\r
+ XtGetValues(edit, args, j);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNheight, &pw_height); j++;\r
+ XtGetValues(shell, args, j);\r
+ commentH = pw_height + (lines - 1) * ew_height;\r
+ commentW = bw_width - 16;\r
+\r
+ XSync(xDisplay, False);\r
+#ifdef NOTDEF\r
+ /* This code seems to tickle an X bug if it is executed too soon\r
+ after xboard starts up. The coordinates get transformed as if\r
+ the main window was positioned at (0, 0).\r
+ */\r
+ XtTranslateCoords(shellWidget,\r
+ (bw_width - commentW) / 2, 0 - commentH / 2,\r
+ &commentX, &commentY);\r
+#else /*!NOTDEF*/\r
+ XTranslateCoordinates(xDisplay, XtWindow(shellWidget),\r
+ RootWindowOfScreen(XtScreen(shellWidget)),\r
+ (bw_width - commentW) / 2, 0 - commentH / 2,\r
+ &xx, &yy, &junk);\r
+ commentX = xx;\r
+ commentY = yy;\r
+#endif /*!NOTDEF*/\r
+ if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/\r
+ }\r
+ j = 0;\r
+ XtSetArg(args[j], XtNheight, commentH); j++;\r
+ XtSetArg(args[j], XtNwidth, commentW); j++;\r
+ XtSetArg(args[j], XtNx, commentX); j++;\r
+ XtSetArg(args[j], XtNy, commentY); j++;\r
+ XtSetValues(shell, args, j);\r
+ XtSetKeyboardFocus(shell, edit);\r
+\r
+ return shell;\r
+}\r
+\r
+/* Used for analysis window and ICS input window */\r
+Widget MiscCreate(name, text, mutable, callback, lines)\r
+ char *name, *text;\r
+ int /*Boolean*/ mutable;\r
+ XtCallbackProc callback;\r
+ int lines;\r
+{\r
+ Arg args[16];\r
+ Widget shell, layout, form, edit;\r
+ Position x, y;\r
+ Dimension bw_width, pw_height, ew_height, w, h;\r
+ int j;\r
+ int xx, yy;\r
+ Window junk;\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNresizable, True); j++;\r
+#if TOPLEVEL\r
+ shell =\r
+ XtCreatePopupShell(name, topLevelShellWidgetClass,\r
+ shellWidget, args, j);\r
+#else\r
+ shell =\r
+ XtCreatePopupShell(name, transientShellWidgetClass,\r
+ shellWidget, args, j);\r
+#endif\r
+ layout =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, shell,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ form =\r
+ XtCreateManagedWidget("form", formWidgetClass, layout,\r
+ formArgs, XtNumber(formArgs));\r
+\r
+ j = 0;\r
+ if (mutable) {\r
+ XtSetArg(args[j], XtNeditType, XawtextEdit); j++;\r
+ XtSetArg(args[j], XtNuseStringInPlace, False); j++;\r
+ }\r
+ XtSetArg(args[j], XtNstring, text); j++;\r
+ XtSetArg(args[j], XtNtop, XtChainTop); j++;\r
+ XtSetArg(args[j], XtNbottom, XtChainBottom); j++;\r
+ XtSetArg(args[j], XtNleft, XtChainLeft); j++;\r
+ XtSetArg(args[j], XtNright, XtChainRight); j++;\r
+ XtSetArg(args[j], XtNresizable, True); j++;\r
+#if 0\r
+ XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;\r
+#else\r
+ /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */\r
+ XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;\r
+#endif\r
+ XtSetArg(args[j], XtNautoFill, True); j++;\r
+ XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;\r
+ edit =\r
+ XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);\r
+\r
+ XtRealizeWidget(shell);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNwidth, &bw_width); j++;\r
+ XtGetValues(boardWidget, args, j);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNheight, &ew_height); j++;\r
+ XtGetValues(edit, args, j);\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNheight, &pw_height); j++;\r
+ XtGetValues(shell, args, j);\r
+ h = pw_height + (lines - 1) * ew_height;\r
+ w = bw_width - 16;\r
+\r
+ XSync(xDisplay, False);\r
+#ifdef NOTDEF\r
+ /* This code seems to tickle an X bug if it is executed too soon\r
+ after xboard starts up. The coordinates get transformed as if\r
+ the main window was positioned at (0, 0).\r
+ */\r
+ XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);\r
+#else /*!NOTDEF*/\r
+ XTranslateCoordinates(xDisplay, XtWindow(shellWidget),\r
+ RootWindowOfScreen(XtScreen(shellWidget)),\r
+ (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);\r
+#endif /*!NOTDEF*/\r
+ x = xx;\r
+ y = yy;\r
+ if (y < 0) y = 0; /*avoid positioning top offscreen*/\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNheight, h); j++;\r
+ XtSetArg(args[j], XtNwidth, w); j++;\r
+ XtSetArg(args[j], XtNx, x); j++;\r
+ XtSetArg(args[j], XtNy, y); j++;\r
+ XtSetValues(shell, args, j);\r
+\r
+ return shell;\r
+}\r
+\r
+\r
+static int savedIndex; /* gross that this is global */\r
+\r
+void EditCommentPopUp(index, title, text)\r
+ int index;\r
+ char *title, *text;\r
+{\r
+ Widget edit;\r
+ Arg args[16];\r
+ int j;\r
+\r
+ savedIndex = index;\r
+ if (text == NULL) text = "";\r
+\r
+ if (editShell == NULL) {\r
+ editShell =\r
+ CommentCreate(title, text, True, EditCommentCallback, 4); \r
+ XtRealizeWidget(editShell);\r
+ CatchDeleteWindow(editShell, "EditCommentPopDown");\r
+ } else {\r
+ edit = XtNameToWidget(editShell, "*form.text");\r
+ j = 0;\r
+ XtSetArg(args[j], XtNstring, text); j++;\r
+ XtSetValues(edit, args, j);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;\r
+ XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;\r
+ XtSetValues(editShell, args, j);\r
+ }\r
+\r
+ XtPopup(editShell, XtGrabNone);\r
+\r
+ editUp = True;\r
+ j = 0;\r
+ XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),\r
+ args, j);\r
+}\r
+\r
+void EditCommentCallback(w, client_data, call_data)\r
+ Widget w;\r
+ XtPointer client_data, call_data;\r
+{\r
+ String name, val;\r
+ Arg args[16];\r
+ int j;\r
+ Widget edit;\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNlabel, &name); j++;\r
+ XtGetValues(w, args, j);\r
+\r
+ if (strcmp(name, "ok") == 0) {\r
+ edit = XtNameToWidget(editShell, "*form.text");\r
+ j = 0;\r
+ XtSetArg(args[j], XtNstring, &val); j++;\r
+ XtGetValues(edit, args, j);\r
+ ReplaceComment(savedIndex, val);\r
+ EditCommentPopDown();\r
+ } else if (strcmp(name, "cancel") == 0) {\r
+ EditCommentPopDown();\r
+ } else if (strcmp(name, "clear") == 0) {\r
+ edit = XtNameToWidget(editShell, "*form.text");\r
+ XtCallActionProc(edit, "select-all", NULL, NULL, 0);\r
+ XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);\r
+ }\r
+}\r
+\r
+void EditCommentPopDown()\r
+{\r
+ Arg args[16];\r
+ int j;\r
+\r
+ if (!editUp) return;\r
+ j = 0;\r
+ XtSetArg(args[j], XtNx, &commentX); j++;\r
+ XtSetArg(args[j], XtNy, &commentY); j++;\r
+ XtSetArg(args[j], XtNheight, &commentH); j++;\r
+ XtSetArg(args[j], XtNwidth, &commentW); j++;\r
+ XtGetValues(editShell, args, j);\r
+ XtPopdown(editShell);\r
+ editUp = False;\r
+ j = 0;\r
+ XtSetArg(args[j], XtNleftBitmap, None); j++;\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),\r
+ args, j);\r
+}\r
+\r
+void ICSInputBoxPopUp()\r
+{\r
+ Widget edit;\r
+ Arg args[16];\r
+ int j;\r
+ char *title = "ICS Input";\r
+ XtTranslations tr;\r
+ \r
+ if (ICSInputShell == NULL) {\r
+ ICSInputShell = MiscCreate(title, "", True, NULL, 1);\r
+ tr = XtParseTranslationTable(ICSInputTranslations);\r
+ edit = XtNameToWidget(ICSInputShell, "*form.text");\r
+ XtOverrideTranslations(edit, tr);\r
+ XtRealizeWidget(ICSInputShell);\r
+ CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");\r
+ \r
+ } else {\r
+ edit = XtNameToWidget(ICSInputShell, "*form.text");\r
+ j = 0;\r
+ XtSetArg(args[j], XtNstring, ""); j++;\r
+ XtSetValues(edit, args, j);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;\r
+ XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;\r
+ XtSetValues(ICSInputShell, args, j);\r
+ }\r
+\r
+ XtPopup(ICSInputShell, XtGrabNone);\r
+ XtSetKeyboardFocus(ICSInputShell, edit);\r
+\r
+ ICSInputBoxUp = True;\r
+ j = 0;\r
+ XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),\r
+ args, j);\r
+}\r
+\r
+void ICSInputSendText()\r
+{\r
+ Widget edit;\r
+ int j;\r
+ Arg args[16];\r
+ String val;\r
+ \r
+ edit = XtNameToWidget(ICSInputShell, "*form.text");\r
+ j = 0;\r
+ XtSetArg(args[j], XtNstring, &val); j++;\r
+ XtGetValues(edit, args, j);\r
+ SendMultiLineToICS(val);\r
+ XtCallActionProc(edit, "select-all", NULL, NULL, 0);\r
+ XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);\r
+}\r
+\r
+void ICSInputBoxPopDown()\r
+{\r
+ Arg args[16];\r
+ int j;\r
+\r
+ if (!ICSInputBoxUp) return;\r
+ j = 0;\r
+ XtPopdown(ICSInputShell);\r
+ ICSInputBoxUp = False;\r
+ j = 0;\r
+ XtSetArg(args[j], XtNleftBitmap, None); j++;\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),\r
+ args, j);\r
+}\r
+\r
+void CommentPopUp(title, text)\r
+ char *title, *text;\r
+{\r
+ Arg args[16];\r
+ int j;\r
+ Widget edit;\r
+\r
+ if (commentShell == NULL) {\r
+ commentShell =\r
+ CommentCreate(title, text, False, CommentCallback, 4);\r
+ XtRealizeWidget(commentShell);\r
+ CatchDeleteWindow(commentShell, "CommentPopDown");\r
+ } else {\r
+ edit = XtNameToWidget(commentShell, "*form.text");\r
+ j = 0;\r
+ XtSetArg(args[j], XtNstring, text); j++;\r
+ XtSetValues(edit, args, j);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;\r
+ XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;\r
+ XtSetValues(commentShell, args, j);\r
+ }\r
+\r
+ XtPopup(commentShell, XtGrabNone);\r
+ XSync(xDisplay, False);\r
+\r
+ commentUp = True;\r
+}\r
+\r
+void AnalysisPopUp(title, text)\r
+ char *title, *text;\r
+{\r
+ Arg args[16];\r
+ int j;\r
+ Widget edit;\r
+\r
+ if (analysisShell == NULL) {\r
+ analysisShell = MiscCreate(title, text, False, NULL, 4);\r
+ XtRealizeWidget(analysisShell);\r
+ CatchDeleteWindow(analysisShell, "AnalysisPopDown");\r
+\r
+ } else {\r
+ edit = XtNameToWidget(analysisShell, "*form.text");\r
+ j = 0;\r
+ XtSetArg(args[j], XtNstring, text); j++;\r
+ XtSetValues(edit, args, j);\r
+ j = 0;\r
+ XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;\r
+ XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;\r
+ XtSetValues(analysisShell, args, j);\r
+ }\r
+\r
+ if (!analysisUp) {\r
+ XtPopup(analysisShell, XtGrabNone);\r
+ }\r
+ XSync(xDisplay, False);\r
+\r
+ analysisUp = True;\r
+}\r
+\r
+void CommentCallback(w, client_data, call_data)\r
+ Widget w;\r
+ XtPointer client_data, call_data;\r
+{\r
+ String name;\r
+ Arg args[16];\r
+ int j;\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNlabel, &name); j++;\r
+ XtGetValues(w, args, j);\r
+\r
+ if (strcmp(name, "close") == 0) {\r
+ CommentPopDown();\r
+ } else if (strcmp(name, "edit") == 0) {\r
+ CommentPopDown();\r
+ EditCommentEvent();\r
+ }\r
+}\r
+\r
+\r
+void CommentPopDown()\r
+{\r
+ Arg args[16];\r
+ int j;\r
+\r
+ if (!commentUp) return;\r
+ j = 0;\r
+ XtSetArg(args[j], XtNx, &commentX); j++;\r
+ XtSetArg(args[j], XtNy, &commentY); j++;\r
+ XtSetArg(args[j], XtNwidth, &commentW); j++;\r
+ XtSetArg(args[j], XtNheight, &commentH); j++;\r
+ XtGetValues(commentShell, args, j);\r
+ XtPopdown(commentShell);\r
+ XSync(xDisplay, False);\r
+ commentUp = False;\r
+}\r
+\r
+void AnalysisPopDown()\r
+{\r
+ if (!analysisUp) return;\r
+ XtPopdown(analysisShell);\r
+ XSync(xDisplay, False);\r
+ analysisUp = False;\r
+}\r
+\r
+\r
+void FileNamePopUp(label, def, proc, openMode)\r
+ char *label;\r
+ char *def;\r
+ FileProc proc;\r
+ char *openMode;\r
+{\r
+ Arg args[16];\r
+ Widget popup, layout, dialog, edit;\r
+ Window root, child;\r
+ int x, y, i;\r
+ int win_x, win_y;\r
+ unsigned int mask;\r
+ \r
+ fileProc = proc; /* I can't see a way not */\r
+ fileOpenMode = openMode; /* to use globals here */\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNresizable, True); i++;\r
+ XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;\r
+ fileNameShell = popup =\r
+ XtCreatePopupShell("File name prompt", transientShellWidgetClass,\r
+ shellWidget, args, i);\r
+ \r
+ layout =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNlabel, label); i++;\r
+ XtSetArg(args[i], XtNvalue, def); i++;\r
+ XtSetArg(args[i], XtNborderWidth, 0); i++;\r
+ dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,\r
+ layout, args, i);\r
+ \r
+ XawDialogAddButton(dialog, "ok", FileNameCallback, (XtPointer) dialog);\r
+ XawDialogAddButton(dialog, "cancel", FileNameCallback,\r
+ (XtPointer) dialog);\r
+ \r
+ XtRealizeWidget(popup);\r
+ CatchDeleteWindow(popup, "FileNamePopDown");\r
+ \r
+ XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
+ &x, &y, &win_x, &win_y, &mask);\r
+ \r
+ XtSetArg(args[0], XtNx, x - 10);\r
+ XtSetArg(args[1], XtNy, y - 30);\r
+ XtSetValues(popup, args, 2);\r
+ \r
+ XtPopup(popup, XtGrabExclusive);\r
+ filenameUp = True;\r
+ \r
+ edit = XtNameToWidget(dialog, "*value");\r
+ XtSetKeyboardFocus(popup, edit);\r
+}\r
+\r
+void FileNamePopDown()\r
+{\r
+ if (!filenameUp) return;\r
+ XtPopdown(fileNameShell);\r
+ XtDestroyWidget(fileNameShell);\r
+ filenameUp = False;\r
+ ModeHighlight();\r
+}\r
+\r
+void FileNameCallback(w, client_data, call_data)\r
+ Widget w;\r
+ XtPointer client_data, call_data;\r
+{\r
+ String name;\r
+ Arg args[16];\r
+ \r
+ XtSetArg(args[0], XtNlabel, &name);\r
+ XtGetValues(w, args, 1);\r
+ \r
+ if (strcmp(name, "cancel") == 0) {\r
+ FileNamePopDown();\r
+ return;\r
+ }\r
+ \r
+ FileNameAction(w, NULL, NULL, NULL);\r
+}\r
+\r
+void FileNameAction(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ char buf[MSG_SIZ];\r
+ String name;\r
+ FILE *f;\r
+ char *p, *fullname;\r
+ int index;\r
+\r
+ name = XawDialogGetValueString(w = XtParent(w));\r
+ \r
+ if ((name != NULL) && (*name != NULLCHAR)) {\r
+ strcpy(buf, name);\r
+ XtPopdown(w = XtParent(XtParent(w)));\r
+ XtDestroyWidget(w);\r
+ filenameUp = False;\r
+\r
+ p = strrchr(buf, ' ');\r
+ if (p == NULL) {\r
+ index = 0;\r
+ } else {\r
+ *p++ = NULLCHAR;\r
+ index = atoi(p);\r
+ }\r
+ fullname = ExpandPathName(buf);\r
+ if (!fullname) {\r
+ ErrorPopUp("Error", "Can't open file", FALSE);\r
+ }\r
+ else {\r
+ f = fopen(fullname, fileOpenMode);\r
+ if (f == NULL) {\r
+ DisplayError("Failed to open file", errno);\r
+ } else {\r
+ (void) (*fileProc)(f, index, buf);\r
+ }\r
+ }\r
+ ModeHighlight();\r
+ return;\r
+ }\r
+ \r
+ XtPopdown(w = XtParent(XtParent(w)));\r
+ XtDestroyWidget(w);\r
+ filenameUp = False;\r
+ ModeHighlight();\r
+}\r
+\r
+void PromotionPopUp()\r
+{\r
+ Arg args[16];\r
+ Widget dialog, layout;\r
+ Position x, y;\r
+ Dimension bw_width, pw_width;\r
+ int j;\r
+\r
+ j = 0;\r
+ XtSetArg(args[j], XtNwidth, &bw_width); j++;\r
+ XtGetValues(boardWidget, args, j);\r
+ \r
+ j = 0;\r
+ XtSetArg(args[j], XtNresizable, True); j++;\r
+ promotionShell =\r
+ XtCreatePopupShell("Promotion", transientShellWidgetClass,\r
+ shellWidget, args, j);\r
+ layout =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ \r
+ j = 0;\r
+ XtSetArg(args[j], XtNlabel, "Promote pawn to what?"); j++;\r
+ XtSetArg(args[j], XtNborderWidth, 0); j++;\r
+ dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,\r
+ layout, args, j);\r
+ \r
+ XawDialogAddButton(dialog, "Queen", PromotionCallback, \r
+ (XtPointer) dialog);\r
+ XawDialogAddButton(dialog, "Rook", PromotionCallback, \r
+ (XtPointer) dialog);\r
+ XawDialogAddButton(dialog, "Bishop", PromotionCallback, \r
+ (XtPointer) dialog);\r
+ XawDialogAddButton(dialog, "Knight", PromotionCallback, \r
+ (XtPointer) dialog);\r
+ if (!appData.testLegality || gameInfo.variant == VariantSuicide ||\r
+ gameInfo.variant == VariantGiveaway) {\r
+ XawDialogAddButton(dialog, "King", PromotionCallback, \r
+ (XtPointer) dialog);\r
+ }\r
+ XawDialogAddButton(dialog, "cancel", PromotionCallback, \r
+ (XtPointer) dialog);\r
+ \r
+ XtRealizeWidget(promotionShell);\r
+ CatchDeleteWindow(promotionShell, "PromotionPopDown");\r
+ \r
+ j = 0;\r
+ XtSetArg(args[j], XtNwidth, &pw_width); j++;\r
+ XtGetValues(promotionShell, args, j);\r
+ \r
+ XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,\r
+ lineGap + squareSize/3 +\r
+ ((toY == BOARD_HEIGHT-1) ^ (flipView) ?\r
+ 0 : 6*(squareSize + lineGap)), &x, &y);\r
+ \r
+ j = 0;\r
+ XtSetArg(args[j], XtNx, x); j++;\r
+ XtSetArg(args[j], XtNy, y); j++;\r
+ XtSetValues(promotionShell, args, j);\r
+ \r
+ XtPopup(promotionShell, XtGrabNone);\r
+ \r
+ promotionUp = True;\r
+}\r
+\r
+void PromotionPopDown()\r
+{\r
+ if (!promotionUp) return;\r
+ XtPopdown(promotionShell);\r
+ XtDestroyWidget(promotionShell);\r
+ promotionUp = False;\r
+}\r
+\r
+void PromotionCallback(w, client_data, call_data)\r
+ Widget w;\r
+ XtPointer client_data, call_data;\r
+{\r
+ String name;\r
+ Arg args[16];\r
+ int promoChar;\r
+ \r
+ XtSetArg(args[0], XtNlabel, &name);\r
+ XtGetValues(w, args, 1);\r
+ \r
+ PromotionPopDown();\r
+ \r
+ if (fromX == -1) return;\r
+ \r
+ if (strcmp(name, "cancel") == 0) {\r
+ fromX = fromY = -1;\r
+ ClearHighlights();\r
+ return;\r
+ } else if (strcmp(name, "Knight") == 0) {\r
+ promoChar = 'n';\r
+ } else {\r
+ promoChar = ToLower(name[0]);\r
+ }\r
+\r
+ UserMoveEvent(fromX, fromY, toX, toY, promoChar);\r
+\r
+ if (!appData.highlightLastMove || gotPremove) ClearHighlights();\r
+ if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
+ fromX = fromY = -1;\r
+}\r
+\r
+\r
+void ErrorCallback(w, client_data, call_data)\r
+ Widget w;\r
+ XtPointer client_data, call_data;\r
+{\r
+ errorUp = False;\r
+ XtPopdown(w = XtParent(XtParent(XtParent(w))));\r
+ XtDestroyWidget(w);\r
+ if (errorExitStatus != -1) ExitEvent(errorExitStatus);\r
+}\r
+\r
+\r
+void ErrorPopDown()\r
+{\r
+ if (!errorUp) return;\r
+ errorUp = False;\r
+ XtPopdown(errorShell);\r
+ XtDestroyWidget(errorShell);\r
+ if (errorExitStatus != -1) ExitEvent(errorExitStatus);\r
+}\r
+\r
+void ErrorPopUp(title, label, modal)\r
+ char *title, *label;\r
+ int modal;\r
+{\r
+ Arg args[16];\r
+ Widget dialog, layout;\r
+ Position x, y;\r
+ int xx, yy;\r
+ Window junk;\r
+ Dimension bw_width, pw_width;\r
+ Dimension pw_height;\r
+ int i;\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNresizable, True); i++;\r
+ XtSetArg(args[i], XtNtitle, title); i++;\r
+ errorShell = \r
+ XtCreatePopupShell("errorpopup", transientShellWidgetClass,\r
+ shellWidget, args, i);\r
+ layout =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNlabel, label); i++;\r
+ XtSetArg(args[i], XtNborderWidth, 0); i++;\r
+ dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,\r
+ layout, args, i);\r
+ \r
+ XawDialogAddButton(dialog, "ok", ErrorCallback, (XtPointer) dialog);\r
+ \r
+ XtRealizeWidget(errorShell);\r
+ CatchDeleteWindow(errorShell, "ErrorPopDown");\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNwidth, &bw_width); i++;\r
+ XtGetValues(boardWidget, args, i);\r
+ i = 0;\r
+ XtSetArg(args[i], XtNwidth, &pw_width); i++;\r
+ XtSetArg(args[i], XtNheight, &pw_height); i++;\r
+ XtGetValues(errorShell, args, i);\r
+\r
+#ifdef NOTDEF\r
+ /* This code seems to tickle an X bug if it is executed too soon\r
+ after xboard starts up. The coordinates get transformed as if\r
+ the main window was positioned at (0, 0).\r
+ */\r
+ XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,\r
+ 0 - pw_height + squareSize / 3, &x, &y);\r
+#else\r
+ XTranslateCoordinates(xDisplay, XtWindow(boardWidget),\r
+ RootWindowOfScreen(XtScreen(boardWidget)),\r
+ (bw_width - pw_width) / 2,\r
+ 0 - pw_height + squareSize / 3, &xx, &yy, &junk);\r
+ x = xx;\r
+ y = yy;\r
+#endif\r
+ if (y < 0) y = 0; /*avoid positioning top offscreen*/\r
+\r
+ i = 0;\r
+ XtSetArg(args[i], XtNx, x); i++;\r
+ XtSetArg(args[i], XtNy, y); i++;\r
+ XtSetValues(errorShell, args, i);\r
+\r
+ errorUp = True;\r
+ XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);\r
+}\r
+\r
+/* Disable all user input other than deleting the window */\r
+static int frozen = 0;\r
+void FreezeUI()\r
+{\r
+ if (frozen) return;\r
+ /* Grab by a widget that doesn't accept input */\r
+ XtAddGrab(messageWidget, TRUE, FALSE);\r
+ frozen = 1;\r
+}\r
+\r
+/* Undo a FreezeUI */\r
+void ThawUI()\r
+{\r
+ if (!frozen) return;\r
+ XtRemoveGrab(messageWidget);\r
+ frozen = 0;\r
+}\r
+\r
+char *ModeToWidgetName(mode)\r
+ GameMode mode;\r
+{\r
+ switch (mode) {\r
+ case BeginningOfGame:\r
+ if (appData.icsActive)\r
+ return "menuMode.ICS Client";\r
+ else if (appData.noChessProgram ||\r
+ *appData.cmailGameName != NULLCHAR)\r
+ return "menuMode.Edit Game";\r
+ else\r
+ return "menuMode.Machine Black";\r
+ case MachinePlaysBlack:\r
+ return "menuMode.Machine Black";\r
+ case MachinePlaysWhite:\r
+ return "menuMode.Machine White";\r
+ case AnalyzeMode:\r
+ return "menuMode.Analysis Mode";\r
+ case AnalyzeFile:\r
+ return "menuMode.Analyze File";\r
+ case TwoMachinesPlay:\r
+ return "menuMode.Two Machines";\r
+ case EditGame:\r
+ return "menuMode.Edit Game";\r
+ case PlayFromGameFile:\r
+ return "menuFile.Load Game";\r
+ case EditPosition:\r
+ return "menuMode.Edit Position";\r
+ case Training:\r
+ return "menuMode.Training";\r
+ case IcsPlayingWhite:\r
+ case IcsPlayingBlack:\r
+ case IcsObserving:\r
+ case IcsIdle:\r
+ case IcsExamining:\r
+ return "menuMode.ICS Client";\r
+ default:\r
+ case EndOfGame:\r
+ return NULL;\r
+ }\r
+} \r
+\r
+void ModeHighlight()\r
+{\r
+ Arg args[16];\r
+ static int oldPausing = FALSE;\r
+ static GameMode oldmode = (GameMode) -1;\r
+ char *wname;\r
+ \r
+ if (!boardWidget || !XtIsRealized(boardWidget)) return;\r
+\r
+ if (pausing != oldPausing) {\r
+ oldPausing = pausing;\r
+ if (pausing) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),\r
+ args, 1);\r
+\r
+ if (appData.showButtonBar) {\r
+#if 0\r
+ if (pausing) {\r
+ XtSetArg(args[0], XtNbackground, buttonForegroundPixel);\r
+ XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);\r
+ } else {\r
+ XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);\r
+ XtSetArg(args[1], XtNforeground, buttonForegroundPixel);\r
+ }\r
+#else\r
+ /* Always toggle, don't set. Previous code messes up when\r
+ invoked while the button is pressed, as releasing it\r
+ toggles the state again. */\r
+ {\r
+ Pixel oldbg, oldfg;\r
+ XtSetArg(args[0], XtNbackground, &oldbg);\r
+ XtSetArg(args[1], XtNforeground, &oldfg);\r
+ XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),\r
+ args, 2);\r
+ XtSetArg(args[0], XtNbackground, oldfg);\r
+ XtSetArg(args[1], XtNforeground, oldbg);\r
+ }\r
+#endif\r
+ XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);\r
+ }\r
+ }\r
+\r
+ wname = ModeToWidgetName(oldmode);\r
+ if (wname != NULL) {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);\r
+ }\r
+ wname = ModeToWidgetName(gameMode);\r
+ if (wname != NULL) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);\r
+ }\r
+ oldmode = gameMode;\r
+\r
+ /* Maybe all the enables should be handled here, not just this one */\r
+ XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),\r
+ gameMode == Training || gameMode == PlayFromGameFile);\r
+}\r
+\r
+\r
+/*\r
+ * Button/menu procedures\r
+ */\r
+void ResetProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ResetGameEvent();\r
+ AnalysisPopDown();\r
+}\r
+\r
+int LoadGamePopUp(f, gameNumber, title)\r
+ FILE *f;\r
+ int gameNumber;\r
+ char *title;\r
+{\r
+ cmailMsgLoaded = FALSE;\r
+ if (gameNumber == 0) {\r
+ int error = GameListBuild(f);\r
+ if (error) {\r
+ DisplayError("Cannot build game list", error);\r
+ } else if (!ListEmpty(&gameList) &&\r
+ ((ListGame *) gameList.tailPred)->number > 1) {\r
+ GameListPopUp(f, title);\r
+ return TRUE;\r
+ }\r
+ GameListDestroy();\r
+ gameNumber = 1;\r
+ }\r
+ return LoadGame(f, gameNumber, title, FALSE);\r
+}\r
+\r
+void LoadGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {\r
+ Reset(FALSE, TRUE);\r
+ }\r
+ FileNamePopUp("Load game file name?", "", LoadGamePopUp, "rb");\r
+}\r
+\r
+void LoadNextGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadGame(1);\r
+}\r
+\r
+void LoadPrevGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadGame(-1);\r
+}\r
+\r
+void ReloadGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadGame(0);\r
+}\r
+\r
+void LoadNextPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadPosition(1);\r
+}\r
+\r
+void LoadPrevPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadPosition(-1);\r
+}\r
+\r
+void ReloadPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadPosition(0);\r
+}\r
+\r
+void LoadPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {\r
+ Reset(FALSE, TRUE);\r
+ }\r
+ FileNamePopUp("Load position file name?", "", LoadPosition, "rb");\r
+}\r
+\r
+void SaveGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ FileNamePopUp("Save game file name?",\r
+ DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),\r
+ SaveGame, "a");\r
+}\r
+\r
+void SavePositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ FileNamePopUp("Save position file name?",\r
+ DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),\r
+ SavePosition, "a");\r
+}\r
+\r
+void ReloadCmailMsgProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ReloadCmailMsgEvent(FALSE);\r
+}\r
+\r
+void MailMoveProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ MailMoveEvent();\r
+}\r
+\r
+/* this variable is shared between CopyPositionProc and SendPositionSelection */\r
+static char *selected_fen_position=NULL;\r
+\r
+static Boolean\r
+SendPositionSelection(Widget w, Atom *selection, Atom *target,\r
+ Atom *type_return, XtPointer *value_return,\r
+ unsigned long *length_return, int *format_return)\r
+{\r
+ char *selection_tmp;\r
+\r
+ if (!selected_fen_position) return False; /* should never happen */\r
+ if (*target == XA_STRING){\r
+ /* note: since no XtSelectionDoneProc was registered, Xt will\r
+ * automatically call XtFree on the value returned. So have to\r
+ * make a copy of it allocated with XtMalloc */\r
+ selection_tmp= XtMalloc(strlen(selected_fen_position)+16);\r
+ strcpy(selection_tmp, selected_fen_position);\r
+\r
+ *value_return=selection_tmp;\r
+ *length_return=strlen(selection_tmp);\r
+ *type_return=XA_STRING;\r
+ *format_return = 8; /* bits per byte */\r
+ return True;\r
+ } else {\r
+ return False;\r
+ } \r
+}\r
+\r
+/* note: when called from menu all parameters are NULL, so no clue what the\r
+ * Widget which was clicked on was, or what the click event was\r
+ */\r
+void CopyPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+ {\r
+ int ret;\r
+\r
+ if (selected_fen_position) free(selected_fen_position);\r
+ selected_fen_position = (char *)PositionToFEN(currentMove,1);\r
+ if (!selected_fen_position) return;\r
+ ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,\r
+ CurrentTime,\r
+ SendPositionSelection,\r
+ NULL/* lose_ownership_proc */ ,\r
+ NULL/* transfer_done_proc */);\r
+ if (!ret) {\r
+ free(selected_fen_position);\r
+ selected_fen_position=NULL;\r
+ }\r
+ }\r
+\r
+/* function called when the data to Paste is ready */\r
+static void\r
+PastePositionCB(Widget w, XtPointer client_data, Atom *selection,\r
+ Atom *type, XtPointer value, unsigned long *len, int *format)\r
+{\r
+ char *fenstr=value;\r
+ if (value==NULL || *len==0) return; /* nothing had been selected to copy */\r
+ fenstr[*len]='\0'; /* normally this string is terminated, but be safe */\r
+ EditPositionPasteFEN(fenstr);\r
+ XtFree(value);\r
+}\r
+\r
+/* called when Paste Position button is pressed,\r
+ * all parameters will be NULL */\r
+void PastePositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,\r
+ /* (XtSelectionCallbackProc) */ PastePositionCB,\r
+ NULL, /* client_data passed to PastePositionCB */\r
+\r
+ /* better to use the time field from the event that triggered the\r
+ * call to this function, but that isn't trivial to get\r
+ */\r
+ CurrentTime\r
+ );\r
+ return;\r
+}\r
+\r
+static Boolean\r
+SendGameSelection(Widget w, Atom *selection, Atom *target,\r
+ Atom *type_return, XtPointer *value_return,\r
+ unsigned long *length_return, int *format_return)\r
+{\r
+ char *selection_tmp;\r
+\r
+ if (*target == XA_STRING){\r
+ FILE* f = fopen(gameCopyFilename, "r");\r
+ long len;\r
+ size_t count;\r
+ if (f == NULL) return False;\r
+ fseek(f, 0, 2);\r
+ len = ftell(f);\r
+ rewind(f);\r
+ selection_tmp = XtMalloc(len + 1);\r
+ count = fread(selection_tmp, 1, len, f);\r
+ if (len != count) {\r
+ XtFree(selection_tmp);\r
+ return False;\r
+ }\r
+ selection_tmp[len] = NULLCHAR;\r
+ *value_return = selection_tmp;\r
+ *length_return = len;\r
+ *type_return = XA_STRING;\r
+ *format_return = 8; /* bits per byte */\r
+ return True;\r
+ } else {\r
+ return False;\r
+ } \r
+}\r
+\r
+/* note: when called from menu all parameters are NULL, so no clue what the\r
+ * Widget which was clicked on was, or what the click event was\r
+ */\r
+void CopyGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ int ret;\r
+\r
+ ret = SaveGameToFile(gameCopyFilename, FALSE);\r
+ if (!ret) return;\r
+\r
+ ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,\r
+ CurrentTime,\r
+ SendGameSelection,\r
+ NULL/* lose_ownership_proc */ ,\r
+ NULL/* transfer_done_proc */);\r
+}\r
+\r
+/* function called when the data to Paste is ready */\r
+static void\r
+PasteGameCB(Widget w, XtPointer client_data, Atom *selection,\r
+ Atom *type, XtPointer value, unsigned long *len, int *format)\r
+{\r
+ FILE* f;\r
+ if (value == NULL || *len == 0) {\r
+ return; /* nothing had been selected to copy */\r
+ }\r
+ f = fopen(gamePasteFilename, "w");\r
+ if (f == NULL) {\r
+ DisplayError("Can't open temp file", errno);\r
+ return;\r
+ }\r
+ fwrite(value, 1, *len, f);\r
+ fclose(f);\r
+ XtFree(value);\r
+ LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);\r
+}\r
+\r
+/* called when Paste Game button is pressed,\r
+ * all parameters will be NULL */\r
+void PasteGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,\r
+ /* (XtSelectionCallbackProc) */ PasteGameCB,\r
+ NULL, /* client_data passed to PasteGameCB */\r
+\r
+ /* better to use the time field from the event that triggered the\r
+ * call to this function, but that isn't trivial to get\r
+ */\r
+ CurrentTime\r
+ );\r
+ return;\r
+}\r
+\r
+\r
+void AutoSaveGame()\r
+{\r
+ SaveGameProc(NULL, NULL, NULL, NULL);\r
+}\r
+\r
+\r
+void QuitProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ExitEvent(0);\r
+}\r
+\r
+void PauseProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ PauseEvent();\r
+}\r
+\r
+\r
+void MachineBlackProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ MachineBlackEvent();\r
+}\r
+\r
+void MachineWhiteProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ MachineWhiteEvent();\r
+}\r
+\r
+void AnalyzeModeProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (!first.analysisSupport) {\r
+ char buf[MSG_SIZ];\r
+ sprintf(buf, "%s does not support analysis", first.tidy);\r
+ DisplayError(buf, 0);\r
+ return;\r
+ }\r
+ if (!appData.showThinking)\r
+ ShowThinkingProc(w,event,prms,nprms);\r
+\r
+ AnalyzeModeEvent();\r
+}\r
+\r
+void AnalyzeFileProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (!first.analysisSupport) {\r
+ char buf[MSG_SIZ];\r
+ sprintf(buf, "%s does not support analysis", first.tidy);\r
+ DisplayError(buf, 0);\r
+ return;\r
+ }\r
+ Reset(FALSE, TRUE);\r
+\r
+ if (!appData.showThinking)\r
+ ShowThinkingProc(w,event,prms,nprms);\r
+\r
+ AnalyzeFileEvent();\r
+ FileNamePopUp("File to analyze", "", LoadGamePopUp, "rb");\r
+ AnalysisPeriodicEvent(1);\r
+}\r
+\r
+void TwoMachinesProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ TwoMachinesEvent();\r
+}\r
+\r
+void IcsClientProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ IcsClientEvent();\r
+}\r
+\r
+void EditGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ EditGameEvent();\r
+}\r
+\r
+void EditPositionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ EditPositionEvent();\r
+}\r
+\r
+void TrainingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ TrainingEvent();\r
+}\r
+\r
+void EditCommentProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (editUp) {\r
+ EditCommentPopDown();\r
+ } else {\r
+ EditCommentEvent();\r
+ }\r
+}\r
+\r
+void IcsInputBoxProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (ICSInputBoxUp) {\r
+ ICSInputBoxPopDown();\r
+ } else {\r
+ ICSInputBoxPopUp();\r
+ }\r
+}\r
+\r
+void AcceptProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ AcceptEvent();\r
+}\r
+\r
+void DeclineProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ DeclineEvent();\r
+}\r
+\r
+void RematchProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ RematchEvent();\r
+}\r
+\r
+void CallFlagProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ CallFlagEvent();\r
+}\r
+\r
+void DrawProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ DrawEvent();\r
+}\r
+\r
+void AbortProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ AbortEvent();\r
+}\r
+\r
+void AdjournProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ AdjournEvent();\r
+}\r
+\r
+void ResignProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ResignEvent();\r
+}\r
+\r
+void EnterKeyProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (ICSInputBoxUp == True)\r
+ ICSInputSendText();\r
+}\r
+\r
+void StopObservingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ StopObservingEvent();\r
+}\r
+\r
+void StopExaminingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ StopExaminingEvent();\r
+}\r
+\r
+\r
+void ForwardProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ForwardEvent();\r
+}\r
+\r
+\r
+void BackwardProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ BackwardEvent();\r
+}\r
+\r
+void ToStartProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ToStartEvent();\r
+}\r
+\r
+void ToEndProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ ToEndEvent();\r
+}\r
+\r
+void RevertProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ RevertEvent();\r
+}\r
+\r
+void TruncateGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ TruncateGameEvent();\r
+}\r
+void RetractMoveProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ RetractMoveEvent();\r
+}\r
+\r
+void MoveNowProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ MoveNowEvent();\r
+}\r
+\r
+\r
+void AlwaysQueenProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;\r
+\r
+ if (appData.alwaysPromoteToQueen) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),\r
+ args, 1);\r
+}\r
+\r
+void AnimateDraggingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.animateDragging = !appData.animateDragging;\r
+\r
+ if (appData.animateDragging) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ CreateAnimVars();\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),\r
+ args, 1);\r
+}\r
+\r
+void AnimateMovingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.animate = !appData.animate;\r
+\r
+ if (appData.animate) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ CreateAnimVars();\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),\r
+ args, 1);\r
+}\r
+\r
+void AutocommProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.autoComment = !appData.autoComment;\r
+\r
+ if (appData.autoComment) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),\r
+ args, 1);\r
+}\r
+\r
+\r
+void AutoflagProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.autoCallFlag = !appData.autoCallFlag;\r
+\r
+ if (appData.autoCallFlag) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),\r
+ args, 1);\r
+}\r
+\r
+void AutoflipProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.autoFlipView = !appData.autoFlipView;\r
+\r
+ if (appData.autoFlipView) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),\r
+ args, 1);\r
+}\r
+\r
+void AutobsProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.autoObserve = !appData.autoObserve;\r
+\r
+ if (appData.autoObserve) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),\r
+ args, 1);\r
+}\r
+\r
+void AutoraiseProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.autoRaiseBoard = !appData.autoRaiseBoard;\r
+\r
+ if (appData.autoRaiseBoard) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),\r
+ args, 1);\r
+}\r
+\r
+void AutosaveProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.autoSaveGames = !appData.autoSaveGames;\r
+\r
+ if (appData.autoSaveGames) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),\r
+ args, 1);\r
+}\r
+\r
+void BlindfoldProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.blindfold = !appData.blindfold;\r
+\r
+ if (appData.blindfold) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),\r
+ args, 1);\r
+\r
+ DrawPosition(True, NULL);\r
+}\r
+\r
+void TestLegalityProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.testLegality = !appData.testLegality;\r
+\r
+ if (appData.testLegality) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),\r
+ args, 1);\r
+}\r
+\r
+\r
+void FlashMovesProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ if (appData.flashCount == 0) {\r
+ appData.flashCount = 3;\r
+ } else {\r
+ appData.flashCount = -appData.flashCount;\r
+ }\r
+\r
+ if (appData.flashCount > 0) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),\r
+ args, 1);\r
+}\r
+\r
+void FlipViewProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ flipView = !flipView;\r
+ DrawPosition(True, NULL);\r
+}\r
+\r
+void GetMoveListProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.getMoveList = !appData.getMoveList;\r
+\r
+ if (appData.getMoveList) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ GetMoveListEvent();\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),\r
+ args, 1);\r
+}\r
+\r
+#if HIGHDRAG\r
+void HighlightDraggingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.highlightDragging = !appData.highlightDragging;\r
+\r
+ if (appData.highlightDragging) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Highlight Dragging"), args, 1);\r
+}\r
+#endif\r
+\r
+void HighlightLastMoveProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.highlightLastMove = !appData.highlightLastMove;\r
+\r
+ if (appData.highlightLastMove) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Highlight Last Move"), args, 1);\r
+}\r
+\r
+void IcsAlarmProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.icsAlarm = !appData.icsAlarm;\r
+\r
+ if (appData.icsAlarm) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.ICS Alarm"), args, 1);\r
+}\r
+\r
+void MoveSoundProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.ringBellAfterMoves = !appData.ringBellAfterMoves;\r
+\r
+ if (appData.ringBellAfterMoves) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),\r
+ args, 1);\r
+}\r
+\r
+\r
+void OldSaveStyleProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.oldSaveStyle = !appData.oldSaveStyle;\r
+\r
+ if (appData.oldSaveStyle) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),\r
+ args, 1);\r
+}\r
+\r
+void PeriodicUpdatesProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ PeriodicUpdatesEvent(!appData.periodicUpdates);\r
+ \r
+ if (appData.periodicUpdates) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),\r
+ args, 1);\r
+}\r
+\r
+void PonderNextMoveProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ PonderNextMoveEvent(!appData.ponderNextMove);\r
+\r
+ if (appData.ponderNextMove) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),\r
+ args, 1);\r
+}\r
+\r
+void PopupExitMessageProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.popupExitMessage = !appData.popupExitMessage;\r
+\r
+ if (appData.popupExitMessage) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Popup Exit Message"), args, 1);\r
+}\r
+\r
+void PopupMoveErrorsProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.popupMoveErrors = !appData.popupMoveErrors;\r
+\r
+ if (appData.popupMoveErrors) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),\r
+ args, 1);\r
+}\r
+\r
+void PremoveProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.premove = !appData.premove;\r
+\r
+ if (appData.premove) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget,\r
+ "menuOptions.Premove"), args, 1);\r
+}\r
+\r
+void QuietPlayProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.quietPlay = !appData.quietPlay;\r
+\r
+ if (appData.quietPlay) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),\r
+ args, 1);\r
+}\r
+\r
+void ShowCoordsProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ appData.showCoords = !appData.showCoords;\r
+\r
+ if (appData.showCoords) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),\r
+ args, 1);\r
+\r
+ DrawPosition(True, NULL);\r
+}\r
+\r
+void ShowThinkingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+\r
+ ShowThinkingEvent(!appData.showThinking);\r
+\r
+ if (appData.showThinking) {\r
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);\r
+ } else {\r
+ XtSetArg(args[0], XtNleftBitmap, None);\r
+ }\r
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),\r
+ args, 1);\r
+}\r
+\r
+void InfoProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ char buf[MSG_SIZ];\r
+ sprintf(buf, "xterm -e info --directory %s --directory . -f %s &",\r
+ INFODIR, INFOFILE);\r
+ system(buf);\r
+}\r
+\r
+void ManProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ char buf[MSG_SIZ];\r
+ String name;\r
+ if (nprms && *nprms > 0)\r
+ name = prms[0];\r
+ else\r
+ name = "xboard";\r
+ sprintf(buf, "xterm -e man %s &", name);\r
+ system(buf);\r
+}\r
+\r
+void HintProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ HintEvent();\r
+}\r
+\r
+void BookProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ BookEvent();\r
+}\r
+\r
+void AboutProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ char buf[MSG_SIZ];\r
+#if ZIPPY\r
+ char *zippy = " (with Zippy code)";\r
+#else\r
+ char *zippy = "";\r
+#endif\r
+ sprintf(buf, "%s%s\n\n%s\n%s\n\n%s%s\n%s",\r
+ programVersion, zippy,\r
+ "Copyright 1991 Digital Equipment Corporation",\r
+ "Enhancements Copyright 1992-2001 Free Software Foundation",\r
+ PRODUCT, " is free software and carries NO WARRANTY;",\r
+ "see the file COPYING for more information.");\r
+ ErrorPopUp("About XBoard", buf, FALSE);\r
+}\r
+\r
+void DebugProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ appData.debugMode = !appData.debugMode;\r
+}\r
+\r
+void AboutGameProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ AboutGameEvent();\r
+}\r
+\r
+void NothingProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ return;\r
+}\r
+\r
+void Iconify(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ Arg args[16];\r
+ \r
+ fromX = fromY = -1;\r
+ XtSetArg(args[0], XtNiconic, True);\r
+ XtSetValues(shellWidget, args, 1);\r
+}\r
+\r
+void DisplayMessage(message, extMessage)\r
+ char *message, *extMessage;\r
+{\r
+ char buf[MSG_SIZ];\r
+ Arg arg;\r
+ \r
+ if (extMessage) {\r
+ if (*message) {\r
+ sprintf(buf, "%s %s", message, extMessage);\r
+ message = buf;\r
+ } else {\r
+ message = extMessage;\r
+ }\r
+ }\r
+ XtSetArg(arg, XtNlabel, message);\r
+ XtSetValues(messageWidget, &arg, 1);\r
+}\r
+\r
+void DisplayTitle(text)\r
+ char *text;\r
+{\r
+ Arg args[16];\r
+ int i;\r
+ char title[MSG_SIZ];\r
+ char icon[MSG_SIZ];\r
+\r
+ if (text == NULL) text = "";\r
+\r
+ if (appData.titleInWindow) {\r
+ i = 0;\r
+ XtSetArg(args[i], XtNlabel, text); i++;\r
+ XtSetValues(titleWidget, args, i);\r
+ }\r
+\r
+ if (*text != NULLCHAR) {\r
+ strcpy(icon, text);\r
+ strcpy(title, text);\r
+ } else if (appData.icsActive) {\r
+ sprintf(icon, "%s", appData.icsHost);\r
+ sprintf(title, "%s: %s", programName, appData.icsHost);\r
+ } else if (appData.cmailGameName[0] != NULLCHAR) {\r
+ sprintf(icon, "%s", "CMail");\r
+ sprintf(title, "%s: %s", programName, "CMail");\r
+ } else if (appData.noChessProgram) {\r
+ strcpy(icon, programName);\r
+ strcpy(title, programName);\r
+ } else {\r
+ strcpy(icon, first.tidy);\r
+ sprintf(title, "%s: %s", programName, first.tidy);\r
+ }\r
+ i = 0;\r
+ XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++;\r
+ XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++;\r
+ XtSetValues(shellWidget, args, i);\r
+}\r
+\r
+\r
+void DisplayError(message, error)\r
+ String message;\r
+ int error;\r
+{\r
+ char buf[MSG_SIZ];\r
+\r
+ if (error == 0) {\r
+ if (appData.debugMode || appData.matchMode) {\r
+ fprintf(stderr, "%s: %s\n", programName, message);\r
+ }\r
+ } else {\r
+ if (appData.debugMode || appData.matchMode) {\r
+ fprintf(stderr, "%s: %s: %s\n",\r
+ programName, message, strerror(error));\r
+ }\r
+ sprintf(buf, "%s: %s", message, strerror(error));\r
+ message = buf;\r
+ } \r
+ ErrorPopUp("Error", message, FALSE);\r
+}\r
+\r
+\r
+void DisplayMoveError(message)\r
+ String message;\r
+{\r
+ fromX = fromY = -1;\r
+ ClearHighlights();\r
+ DrawPosition(FALSE, NULL);\r
+ if (appData.debugMode || appData.matchMode) {\r
+ fprintf(stderr, "%s: %s\n", programName, message);\r
+ }\r
+ if (appData.popupMoveErrors) {\r
+ ErrorPopUp("Error", message, FALSE);\r
+ } else {\r
+ DisplayMessage(message, "");\r
+ }\r
+}\r
+\r
+\r
+void DisplayFatalError(message, error, status)\r
+ String message;\r
+ int error, status;\r
+{\r
+ char buf[MSG_SIZ];\r
+\r
+ errorExitStatus = status;\r
+ if (error == 0) {\r
+ fprintf(stderr, "%s: %s\n", programName, message);\r
+ } else {\r
+ fprintf(stderr, "%s: %s: %s\n",\r
+ programName, message, strerror(error));\r
+ sprintf(buf, "%s: %s", message, strerror(error));\r
+ message = buf;\r
+ }\r
+ if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {\r
+ ErrorPopUp(status ? "Fatal Error" : "Exiting", message, TRUE);\r
+ } else {\r
+ ExitEvent(status);\r
+ }\r
+}\r
+\r
+void DisplayInformation(message)\r
+ String message;\r
+{\r
+ ErrorPopDown();\r
+ ErrorPopUp("Information", message, TRUE);\r
+}\r
+\r
+void DisplayNote(message)\r
+ String message;\r
+{\r
+ ErrorPopDown();\r
+ ErrorPopUp("Note", message, FALSE);\r
+}\r
+\r
+static int\r
+NullXErrorCheck(dpy, error_event)\r
+ Display *dpy;\r
+ XErrorEvent *error_event;\r
+{\r
+ return 0;\r
+}\r
+\r
+void DisplayIcsInteractionTitle(message)\r
+ String message;\r
+{\r
+ if (oldICSInteractionTitle == NULL) {\r
+ /* Magic to find the old window title, adapted from vim */\r
+ char *wina = getenv("WINDOWID");\r
+ if (wina != NULL) {\r
+ Window win = (Window) atoi(wina);\r
+ Window root, parent, *children;\r
+ unsigned int nchildren;\r
+ int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);\r
+ for (;;) {\r
+ if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;\r
+ if (!XQueryTree(xDisplay, win, &root, &parent,\r
+ &children, &nchildren)) break;\r
+ if (children) XFree((void *)children);\r
+ if (parent == root || parent == 0) break;\r
+ win = parent;\r
+ }\r
+ XSetErrorHandler(oldHandler);\r
+ }\r
+ if (oldICSInteractionTitle == NULL) {\r
+ oldICSInteractionTitle = "xterm"; \r
+ }\r
+ } \r
+ printf("\033]0;%s\007", message);\r
+ fflush(stdout);\r
+}\r
+\r
+char pendingReplyPrefix[MSG_SIZ];\r
+ProcRef pendingReplyPR;\r
+\r
+void AskQuestionProc(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ if (*nprms != 4) {\r
+ fprintf(stderr, "AskQuestionProc needed 4 parameters, got %d\n",\r
+ *nprms);\r
+ return;\r
+ }\r
+ AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);\r
+}\r
+\r
+void AskQuestionPopDown()\r
+{\r
+ if (!askQuestionUp) return;\r
+ XtPopdown(askQuestionShell);\r
+ XtDestroyWidget(askQuestionShell);\r
+ askQuestionUp = False;\r
+}\r
+\r
+void AskQuestionReplyAction(w, event, prms, nprms)\r
+ Widget w;\r
+ XEvent *event;\r
+ String *prms;\r
+ Cardinal *nprms;\r
+{\r
+ char buf[MSG_SIZ];\r
+ int err;\r
+ String reply;\r
+\r
+ reply = XawDialogGetValueString(w = XtParent(w));\r
+ strcpy(buf, pendingReplyPrefix);\r
+ if (*buf) strcat(buf, " ");\r
+ strcat(buf, reply);\r
+ strcat(buf, "\n");\r
+ OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);\r
+ AskQuestionPopDown();\r
+\r
+ if (err) DisplayFatalError("Error writing to chess program", err, 0);\r
+}\r
+\r
+void AskQuestionCallback(w, client_data, call_data)\r
+ Widget w;\r
+ XtPointer client_data, call_data;\r
+{\r
+ String name;\r
+ Arg args[16];\r
+\r
+ XtSetArg(args[0], XtNlabel, &name);\r
+ XtGetValues(w, args, 1);\r
+ \r
+ if (strcmp(name, "cancel") == 0) {\r
+ AskQuestionPopDown();\r
+ } else {\r
+ AskQuestionReplyAction(w, NULL, NULL, NULL);\r
+ }\r
+}\r
+\r
+void AskQuestion(title, question, replyPrefix, pr)\r
+ char *title, *question, *replyPrefix;\r
+ ProcRef pr;\r
+{\r
+ Arg args[16];\r
+ Widget popup, layout, dialog, edit;\r
+ Window root, child;\r
+ int x, y, i;\r
+ int win_x, win_y;\r
+ unsigned int mask;\r
+ \r
+ strcpy(pendingReplyPrefix, replyPrefix);\r
+ pendingReplyPR = pr;\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNresizable, True); i++;\r
+ XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;\r
+ askQuestionShell = popup =\r
+ XtCreatePopupShell(title, transientShellWidgetClass,\r
+ shellWidget, args, i);\r
+ \r
+ layout =\r
+ XtCreateManagedWidget(layoutName, formWidgetClass, popup,\r
+ layoutArgs, XtNumber(layoutArgs));\r
+ \r
+ i = 0;\r
+ XtSetArg(args[i], XtNlabel, question); i++;\r
+ XtSetArg(args[i], XtNvalue, ""); i++;\r
+ XtSetArg(args[i], XtNborderWidth, 0); i++;\r
+ dialog = XtCreateManagedWidget("question", dialogWidgetClass,\r
+ layout, args, i);\r
+ \r
+ XawDialogAddButton(dialog, "enter", AskQuestionCallback,\r
+ (XtPointer) dialog);\r
+ XawDialogAddButton(dialog, "cancel", AskQuestionCallback,\r
+ (XtPointer) dialog);\r
+\r
+ XtRealizeWidget(popup);\r
+ CatchDeleteWindow(popup, "AskQuestionPopDown");\r
+ \r
+ XQueryPointer(xDisplay, xBoardWindow, &root, &child,\r
+ &x, &y, &win_x, &win_y, &mask);\r
+ \r
+ XtSetArg(args[0], XtNx, x - 10);\r
+ XtSetArg(args[1], XtNy, y - 30);\r
+ XtSetValues(popup, args, 2);\r
+ \r
+ XtPopup(popup, XtGrabExclusive);\r
+ askQuestionUp = True;\r
+ \r
+ edit = XtNameToWidget(dialog, "*value");\r
+ XtSetKeyboardFocus(popup, edit);\r
+}\r
+\r
+\r
+void\r
+PlaySound(name)\r
+ char *name;\r
+{\r
+ if (*name == NULLCHAR) {\r
+ return;\r
+ } else if (strcmp(name, "$") == 0) {\r
+ putc(BELLCHAR, stderr);\r
+ } else {\r
+ char buf[2048];\r
+ sprintf(buf, "%s '%s' &", appData.soundProgram, name);\r
+ system(buf);\r
+ }\r
+}\r
+\r
+void\r
+RingBell()\r
+{\r
+ PlaySound(appData.soundMove);\r
+}\r
+\r
+void\r
+PlayIcsWinSound()\r
+{\r
+ PlaySound(appData.soundIcsWin);\r
+}\r
+\r
+void\r
+PlayIcsLossSound()\r
+{\r
+ PlaySound(appData.soundIcsLoss);\r
+}\r
+\r
+void\r
+PlayIcsDrawSound()\r
+{\r
+ PlaySound(appData.soundIcsDraw);\r
+}\r
+\r
+void\r
+PlayIcsUnfinishedSound()\r
+{\r
+ PlaySound(appData.soundIcsUnfinished);\r
+}\r
+\r
+void\r
+PlayAlarmSound()\r
+{\r
+ PlaySound(appData.soundIcsAlarm);\r
+}\r
+\r
+void\r
+EchoOn()\r
+{\r
+ system("stty echo");\r
+}\r
+\r
+void\r
+EchoOff()\r
+{\r
+ system("stty -echo");\r
+}\r
+\r
+void\r
+Colorize(cc, continuation)\r
+ ColorClass cc;\r
+ int continuation;\r
+{\r
+ char buf[MSG_SIZ];\r
+ int count, outCount, error;\r
+\r
+ if (textColors[(int)cc].bg > 0) {\r
+ if (textColors[(int)cc].fg > 0) {\r
+ sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,\r
+ textColors[(int)cc].fg, textColors[(int)cc].bg);\r
+ } else {\r
+ sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,\r
+ textColors[(int)cc].bg);\r
+ }\r
+ } else {\r
+ if (textColors[(int)cc].fg > 0) {\r
+ sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,\r
+ textColors[(int)cc].fg);\r
+ } else {\r
+ sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);\r
+ }\r
+ }\r
+ count = strlen(buf);\r
+ outCount = OutputToProcess(NoProc, buf, count, &error);\r
+ if (outCount < count) {\r
+ DisplayFatalError("Error writing to display", error, 1);\r
+ }\r
+\r
+ if (continuation) return;\r
+ switch (cc) {\r
+ case ColorShout:\r
+ PlaySound(appData.soundShout);\r
+ break;\r
+ case ColorSShout:\r
+ PlaySound(appData.soundSShout);\r
+ break;\r
+ case ColorChannel1:\r
+ PlaySound(appData.soundChannel1);\r
+ break;\r
+ case ColorChannel:\r
+ PlaySound(appData.soundChannel);\r
+ break;\r
+ case ColorKibitz:\r
+ PlaySound(appData.soundKibitz);\r
+ break;\r
+ case ColorTell:\r
+ PlaySound(appData.soundTell);\r
+ break;\r
+ case ColorChallenge:\r
+ PlaySound(appData.soundChallenge);\r
+ break;\r
+ case ColorRequest:\r
+ PlaySound(appData.soundRequest);\r
+ break;\r
+ case ColorSeek:\r
+ PlaySound(appData.soundSeek);\r
+ break;\r
+ case ColorNormal:\r
+ case ColorNone:\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+char *UserName()\r
+{\r
+ return getpwuid(getuid())->pw_name;\r
+}\r
+\r
+static char *ExpandPathName(path)\r
+ char *path;\r
+{\r
+ static char static_buf[2000];\r
+ char *d, *s, buf[2000];\r
+ struct passwd *pwd;\r
+ \r
+ s = path;\r
+ d = static_buf;\r
+\r
+ while (*s && isspace(*s))\r
+ ++s;\r
+\r
+ if (!*s) {\r
+ *d = 0;\r
+ return static_buf;\r
+ }\r
+\r
+ if (*s == '~') {\r
+ if (*(s+1) == '/') {\r
+ strcpy(d, getpwuid(getuid())->pw_dir);\r
+ strcat(d, s+1);\r
+ }\r
+ else {\r
+ strcpy(buf, s+1);\r
+ *strchr(buf, '/') = 0;\r
+ pwd = getpwnam(buf);\r
+ if (!pwd)\r
+ {\r
+ fprintf(stderr, "ERROR: Unknown user %s (in path %s)\n",\r
+ buf, path);\r
+ return NULL;\r
+ }\r
+ strcpy(d, pwd->pw_dir);\r
+ strcat(d, strchr(s+1, '/'));\r
+ }\r
+ }\r
+ else\r
+ strcpy(d, s);\r
+\r
+ return static_buf;\r
+} \r
+\r
+char *HostName()\r
+{\r
+ static char host_name[MSG_SIZ];\r
+ \r
+#if HAVE_GETHOSTNAME\r
+ gethostname(host_name, MSG_SIZ);\r
+ return host_name;\r
+#else /* not HAVE_GETHOSTNAME */\r
+# if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H\r
+ sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);\r
+ return host_name;\r
+# else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */\r
+ return "localhost";\r
+# endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */\r
+#endif /* not HAVE_GETHOSTNAME */\r
+}\r
+\r
+XtIntervalId delayedEventTimerXID = 0;\r
+DelayedEventCallback delayedEventCallback = 0;\r
+\r
+void\r
+FireDelayedEvent()\r
+{\r
+ delayedEventTimerXID = 0;\r
+ delayedEventCallback();\r
+}\r
+\r
+void\r
+ScheduleDelayedEvent(cb, millisec)\r
+ DelayedEventCallback cb; long millisec;\r
+{\r
+ delayedEventCallback = cb;\r
+ delayedEventTimerXID =\r
+ XtAppAddTimeOut(appContext, millisec,\r
+ (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);\r
+}\r
+\r
+DelayedEventCallback\r
+GetDelayedEvent()\r
+{\r
+ if (delayedEventTimerXID) {\r
+ return delayedEventCallback;\r
+ } else {\r
+ return NULL;\r
+ }\r
+}\r
+\r
+void\r
+CancelDelayedEvent()\r
+{\r
+ if (delayedEventTimerXID) {\r
+ XtRemoveTimeOut(delayedEventTimerXID);\r
+ delayedEventTimerXID = 0;\r
+ }\r
+}\r
+\r
+XtIntervalId loadGameTimerXID = 0;\r
+\r
+int LoadGameTimerRunning()\r
+{\r
+ return loadGameTimerXID != 0;\r
+}\r
+\r
+int StopLoadGameTimer()\r
+{\r
+ if (loadGameTimerXID != 0) {\r
+ XtRemoveTimeOut(loadGameTimerXID);\r
+ loadGameTimerXID = 0;\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+void\r
+LoadGameTimerCallback(arg, id)\r
+ XtPointer arg;\r
+ XtIntervalId *id;\r
+{\r
+ loadGameTimerXID = 0;\r
+ AutoPlayGameLoop();\r
+}\r
+\r
+void\r
+StartLoadGameTimer(millisec)\r
+ long millisec;\r
+{\r
+ loadGameTimerXID =\r
+ XtAppAddTimeOut(appContext, millisec,\r
+ (XtTimerCallbackProc) LoadGameTimerCallback,\r
+ (XtPointer) 0);\r
+}\r
+\r
+XtIntervalId analysisClockXID = 0;\r
+\r
+void\r
+AnalysisClockCallback(arg, id)\r
+ XtPointer arg;\r
+ XtIntervalId *id;\r
+{\r
+ if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {\r
+ AnalysisPeriodicEvent(0);\r
+ StartAnalysisClock();\r
+ }\r
+}\r
+\r
+void\r
+StartAnalysisClock()\r
+{\r
+ analysisClockXID =\r
+ XtAppAddTimeOut(appContext, 2000,\r
+ (XtTimerCallbackProc) AnalysisClockCallback,\r
+ (XtPointer) 0);\r
+}\r
+\r
+XtIntervalId clockTimerXID = 0;\r
+\r
+int ClockTimerRunning()\r
+{\r
+ return clockTimerXID != 0;\r
+}\r
+\r
+int StopClockTimer()\r
+{\r
+ if (clockTimerXID != 0) {\r
+ XtRemoveTimeOut(clockTimerXID);\r
+ clockTimerXID = 0;\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+void\r
+ClockTimerCallback(arg, id)\r
+ XtPointer arg;\r
+ XtIntervalId *id;\r
+{\r
+ clockTimerXID = 0;\r
+ DecrementClocks();\r
+}\r
+\r
+void\r
+StartClockTimer(millisec)\r
+ long millisec;\r
+{\r
+ clockTimerXID =\r
+ XtAppAddTimeOut(appContext, millisec,\r
+ (XtTimerCallbackProc) ClockTimerCallback,\r
+ (XtPointer) 0);\r
+}\r
+\r
+void\r
+DisplayTimerLabel(w, color, timer, highlight)\r
+ Widget w;\r
+ char *color;\r
+ long timer;\r
+ int highlight;\r
+{\r
+ char buf[MSG_SIZ];\r
+ Arg args[16];\r
+ \r
+ if (appData.clockMode) {\r
+ sprintf(buf, "%s: %s", color, TimeString(timer));\r
+ XtSetArg(args[0], XtNlabel, buf);\r
+ } else {\r
+ sprintf(buf, "%s ", color);\r
+ XtSetArg(args[0], XtNlabel, buf);\r
+ }\r
+ \r
+ if (highlight) {\r
+ XtSetArg(args[1], XtNbackground, timerForegroundPixel);\r
+ XtSetArg(args[2], XtNforeground, timerBackgroundPixel);\r
+ } else {\r
+ XtSetArg(args[1], XtNbackground, timerBackgroundPixel);\r
+ XtSetArg(args[2], XtNforeground, timerForegroundPixel);\r
+ }\r
+ \r
+ XtSetValues(w, args, 3);\r
+}\r
+\r
+void\r
+DisplayWhiteClock(timeRemaining, highlight)\r
+ long timeRemaining;\r
+ int highlight;\r
+{\r
+ Arg args[16];\r
+ DisplayTimerLabel(whiteTimerWidget, "White", timeRemaining, highlight);\r
+ if (highlight && iconPixmap == bIconPixmap) {\r
+ iconPixmap = wIconPixmap;\r
+ XtSetArg(args[0], XtNiconPixmap, iconPixmap);\r
+ XtSetValues(shellWidget, args, 1);\r
+ }\r
+}\r
+\r
+void\r
+DisplayBlackClock(timeRemaining, highlight)\r
+ long timeRemaining;\r
+ int highlight;\r
+{\r
+ Arg args[16];\r
+ DisplayTimerLabel(blackTimerWidget, "Black", timeRemaining, highlight);\r
+ if (highlight && iconPixmap == wIconPixmap) {\r
+ iconPixmap = bIconPixmap;\r
+ XtSetArg(args[0], XtNiconPixmap, iconPixmap);\r
+ XtSetValues(shellWidget, args, 1);\r
+ }\r
+}\r
+\r
+#define CPNone 0\r
+#define CPReal 1\r
+#define CPComm 2\r
+#define CPSock 3\r
+#define CPLoop 4\r
+typedef int CPKind;\r
+\r
+typedef struct {\r
+ CPKind kind;\r
+ int pid;\r
+ int fdTo, fdFrom; \r
+} ChildProc;\r
+\r
+\r
+int StartChildProcess(cmdLine, dir, pr)\r
+ char *cmdLine; \r
+ char *dir;\r
+ ProcRef *pr;\r
+{\r
+ char *argv[64], *p;\r
+ int i, pid;\r
+ int to_prog[2], from_prog[2];\r
+ ChildProc *cp;\r
+ char buf[MSG_SIZ];\r
+ \r
+ if (appData.debugMode) {\r
+ fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);\r
+ }\r
+\r
+ /* We do NOT feed the cmdLine to the shell; we just\r
+ parse it into blank-separated arguments in the\r
+ most simple-minded way possible.\r
+ */\r
+ i = 0;\r
+ strcpy(buf, cmdLine);\r
+ p = buf;\r
+ for (;;) {\r
+ argv[i++] = p;\r
+ p = strchr(p, ' ');\r
+ if (p == NULL) break;\r
+ *p++ = NULLCHAR;\r
+ }\r
+ argv[i] = NULL;\r
+\r
+ SetUpChildIO(to_prog, from_prog);\r
+\r
+ if ((pid = fork()) == 0) {\r
+ /* Child process */\r
+ dup2(to_prog[0], 0);\r
+ dup2(from_prog[1], 1);\r
+ close(to_prog[0]);\r
+ close(to_prog[1]);\r
+ close(from_prog[0]);\r
+ close(from_prog[1]);\r
+ dup2(1, fileno(stderr)); /* force stderr to the pipe */\r
+\r
+ if (dir[0] != NULLCHAR && chdir(dir) != 0) {\r
+ perror(dir);\r
+ exit(1);\r
+ }\r
+\r
+ execvp(argv[0], argv);\r
+ \r
+ /* If we get here, exec failed */\r
+ perror(argv[0]);\r
+ exit(1);\r
+ }\r
+ \r
+ /* Parent process */\r
+ close(to_prog[0]);\r
+ close(from_prog[1]);\r
+ \r
+ cp = (ChildProc *) calloc(1, sizeof(ChildProc));\r
+ cp->kind = CPReal;\r
+ cp->pid = pid;\r
+ cp->fdFrom = from_prog[0];\r
+ cp->fdTo = to_prog[1];\r
+ *pr = (ProcRef) cp;\r
+ return 0;\r
+}\r
+\r
+void\r
+DestroyChildProcess(pr, signal)\r
+ ProcRef pr;\r
+ int signal;\r
+{\r
+ ChildProc *cp = (ChildProc *) pr;\r
+\r
+ if (cp->kind != CPReal) return;\r
+ cp->kind = CPNone;\r
+ if (signal) {\r
+ kill(cp->pid, SIGTERM);\r
+ }\r
+ /* Process is exiting either because of the kill or because of\r
+ a quit command sent by the backend; either way, wait for it to die.\r
+ */\r
+ wait((int *) 0);\r
+ close(cp->fdFrom);\r
+ close(cp->fdTo);\r
+}\r
+\r
+void\r
+InterruptChildProcess(pr)\r
+ ProcRef pr;\r
+{\r
+ ChildProc *cp = (ChildProc *) pr;\r
+\r
+ if (cp->kind != CPReal) return;\r
+ (void) kill(cp->pid, SIGINT); /* stop it thinking */\r
+}\r
+\r
+int OpenTelnet(host, port, pr)\r
+ char *host;\r
+ char *port;\r
+ ProcRef *pr;\r
+{\r
+ char cmdLine[MSG_SIZ];\r
+\r
+ if (port[0] == NULLCHAR) {\r
+ sprintf(cmdLine, "%s %s", appData.telnetProgram, host);\r
+ } else {\r
+ sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);\r
+ }\r
+ return StartChildProcess(cmdLine, "", pr);\r
+}\r
+\r
+int OpenTCP(host, port, pr)\r
+ char *host;\r
+ char *port;\r
+ ProcRef *pr;\r
+{\r
+#if OMIT_SOCKETS\r
+ DisplayFatalError("Socket support is not configured in", 0, 2);\r
+#else /* !OMIT_SOCKETS */\r
+ int s;\r
+ struct sockaddr_in sa;\r
+ struct hostent *hp;\r
+ unsigned short uport;\r
+ ChildProc *cp;\r
+\r
+ if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {\r
+ return errno;\r
+ }\r
+\r
+ memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));\r
+ sa.sin_family = AF_INET;\r
+ sa.sin_addr.s_addr = INADDR_ANY;\r
+ uport = (unsigned short) 0;\r
+ sa.sin_port = htons(uport);\r
+ if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {\r
+ return errno;\r
+ }\r
+\r
+ memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));\r
+ if (!(hp = gethostbyname(host))) {\r
+ int b0, b1, b2, b3;\r
+ if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {\r
+ hp = (struct hostent *) calloc(1, sizeof(struct hostent));\r
+ hp->h_addrtype = AF_INET;\r
+ hp->h_length = 4;\r
+ hp->h_addr_list = (char **) calloc(2, sizeof(char *));\r
+ hp->h_addr_list[0] = (char *) malloc(4);\r
+ hp->h_addr_list[0][0] = b0;\r
+ hp->h_addr_list[0][1] = b1;\r
+ hp->h_addr_list[0][2] = b2;\r
+ hp->h_addr_list[0][3] = b3;\r
+ } else {\r
+ return ENOENT;\r
+ }\r
+ }\r
+ sa.sin_family = hp->h_addrtype;\r
+ uport = (unsigned short) atoi(port);\r
+ sa.sin_port = htons(uport);\r
+ memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);\r
+\r
+ if (connect(s, (struct sockaddr *) &sa, \r
+ sizeof(struct sockaddr_in)) < 0) {\r
+ return errno;\r
+ }\r
+\r
+ cp = (ChildProc *) calloc(1, sizeof(ChildProc));\r
+ cp->kind = CPSock;\r
+ cp->pid = 0;\r
+ cp->fdFrom = s;\r
+ cp->fdTo = s;\r
+ *pr = (ProcRef) cp;\r
+\r
+#endif /* !OMIT_SOCKETS */\r
+\r
+ return 0;\r
+}\r
+\r
+int OpenCommPort(name, pr)\r
+ char *name;\r
+ ProcRef *pr;\r
+{\r
+ int fd;\r
+ ChildProc *cp;\r
+\r
+ fd = open(name, 2, 0);\r
+ if (fd < 0) return errno;\r
+\r
+ cp = (ChildProc *) calloc(1, sizeof(ChildProc));\r
+ cp->kind = CPComm;\r
+ cp->pid = 0;\r
+ cp->fdFrom = fd;\r
+ cp->fdTo = fd;\r
+ *pr = (ProcRef) cp;\r
+\r
+ return 0;\r
+}\r
+\r
+int OpenLoopback(pr)\r
+ ProcRef *pr;\r
+{\r
+ ChildProc *cp;\r
+ int to[2], from[2];\r
+\r
+ SetUpChildIO(to, from);\r
+\r
+ cp = (ChildProc *) calloc(1, sizeof(ChildProc));\r
+ cp->kind = CPLoop;\r
+ cp->pid = 0;\r
+ cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */\r
+ cp->fdTo = to[1];\r
+ *pr = (ProcRef) cp;\r
+\r
+ return 0;\r
+}\r
+\r
+int OpenRcmd(host, user, cmd, pr)\r
+ char *host, *user, *cmd;\r
+ ProcRef *pr;\r
+{\r
+ DisplayFatalError("internal rcmd not implemented for Unix", 0, 1);\r
+ return -1;\r
+} \r
+\r
+#define INPUT_SOURCE_BUF_SIZE 8192\r
+\r
+typedef struct {\r
+ CPKind kind;\r
+ int fd;\r
+ int lineByLine;\r
+ char *unused;\r
+ InputCallback func;\r
+ XtInputId xid;\r
+ char buf[INPUT_SOURCE_BUF_SIZE];\r
+ VOIDSTAR closure;\r
+} InputSource;\r
+\r
+void\r
+DoInputCallback(closure, source, xid) \r
+ caddr_t closure;\r
+ int *source;\r
+ XtInputId *xid;\r
+{\r
+ InputSource *is = (InputSource *) closure;\r
+ int count;\r
+ int error;\r
+ char *p, *q;\r
+\r
+ if (is->lineByLine) {\r
+ count = read(is->fd, is->unused,\r
+ INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));\r
+ if (count <= 0) {\r
+ (is->func)(is, is->closure, is->buf, count, count ? errno : 0);\r
+ return;\r
+ }\r
+ is->unused += count;\r
+ p = is->buf;\r
+ while (p < is->unused) {\r
+ q = memchr(p, '\n', is->unused - p);\r
+ if (q == NULL) break;\r
+ q++;\r
+ (is->func)(is, is->closure, p, q - p, 0);\r
+ p = q;\r
+ }\r
+ q = is->buf;\r
+ while (p < is->unused) {\r
+ *q++ = *p++;\r
+ }\r
+ is->unused = q;\r
+ } else {\r
+ count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);\r
+ if (count == -1)\r
+ error = errno;\r
+ else\r
+ error = 0;\r
+ (is->func)(is, is->closure, is->buf, count, error);\r
+ } \r
+}\r
+\r
+InputSourceRef AddInputSource(pr, lineByLine, func, closure)\r
+ ProcRef pr;\r
+ int lineByLine;\r
+ InputCallback func;\r
+ VOIDSTAR closure;\r
+{\r
+ InputSource *is;\r
+ ChildProc *cp = (ChildProc *) pr;\r
+\r
+ is = (InputSource *) calloc(1, sizeof(InputSource));\r
+ is->lineByLine = lineByLine;\r
+ is->func = func;\r
+ if (pr == NoProc) {\r
+ is->kind = CPReal;\r
+ is->fd = fileno(stdin);\r
+ } else {\r
+ is->kind = cp->kind;\r
+ is->fd = cp->fdFrom;\r
+ }\r
+ if (lineByLine) {\r
+ is->unused = is->buf;\r
+ }\r
+ \r
+ is->xid = XtAppAddInput(appContext, is->fd,\r
+ (XtPointer) (XtInputReadMask),\r
+ (XtInputCallbackProc) DoInputCallback,\r
+ (XtPointer) is);\r
+ is->closure = closure;\r
+ return (InputSourceRef) is;\r
+}\r
+\r
+void\r
+RemoveInputSource(isr)\r
+ InputSourceRef isr;\r
+{\r
+ InputSource *is = (InputSource *) isr;\r
+\r
+ if (is->xid == 0) return;\r
+ XtRemoveInput(is->xid);\r
+ is->xid = 0;\r
+}\r
+\r
+int OutputToProcess(pr, message, count, outError)\r
+ ProcRef pr;\r
+ char *message;\r
+ int count;\r
+ int *outError;\r
+{\r
+ ChildProc *cp = (ChildProc *) pr;\r
+ int outCount;\r
+\r
+ if (pr == NoProc)\r
+ outCount = fwrite(message, 1, count, stdout);\r
+ else\r
+ outCount = write(cp->fdTo, message, count);\r
+\r
+ if (outCount == -1)\r
+ *outError = errno;\r
+ else\r
+ *outError = 0;\r
+\r
+ return outCount;\r
+}\r
+\r
+/* Output message to process, with "ms" milliseconds of delay\r
+ between each character. This is needed when sending the logon\r
+ script to ICC, which for some reason doesn't like the\r
+ instantaneous send. */\r
+int OutputToProcessDelayed(pr, message, count, outError, msdelay)\r
+ ProcRef pr;\r
+ char *message;\r
+ int count;\r
+ int *outError;\r
+ long msdelay;\r
+{\r
+ ChildProc *cp = (ChildProc *) pr;\r
+ int outCount = 0;\r
+ int r;\r
+ \r
+ while (count--) {\r
+ r = write(cp->fdTo, message++, 1);\r
+ if (r == -1) {\r
+ *outError = errno;\r
+ return outCount;\r
+ }\r
+ ++outCount;\r
+ if (msdelay >= 0)\r
+ TimeDelay(msdelay);\r
+ }\r
+\r
+ return outCount;\r
+}\r
+\r
+/**** Animation code by Hugh Fisher, DCS, ANU.\r
+\r
+ Known problem: if a window overlapping the board is\r
+ moved away while a piece is being animated underneath,\r
+ the newly exposed area won't be updated properly.\r
+ I can live with this.\r
+\r
+ Known problem: if you look carefully at the animation\r
+ of pieces in mono mode, they are being drawn as solid\r
+ shapes without interior detail while moving. Fixing\r
+ this would be a major complication for minimal return.\r
+****/\r
+\r
+/* Masks for XPM pieces. Black and white pieces can have\r
+ different shapes, but in the interest of retaining my\r
+ sanity pieces must have the same outline on both light\r
+ and dark squares, and all pieces must use the same\r
+ background square colors/images. */\r
+\r
+static void\r
+CreateAnimMasks (pieceDepth)\r
+ int pieceDepth;\r
+{\r
+ ChessSquare piece;\r
+ Pixmap buf;\r
+ GC bufGC, maskGC;\r
+ int kind, n;\r
+ unsigned long plane;\r
+ XGCValues values;\r
+\r
+ /* Need a bitmap just to get a GC with right depth */\r
+ buf = XCreatePixmap(xDisplay, xBoardWindow,\r
+ 8, 8, 1);\r
+ values.foreground = 1;\r
+ values.background = 0;\r
+ /* Don't use XtGetGC, not read only */\r
+ maskGC = XCreateGC(xDisplay, buf,\r
+ GCForeground | GCBackground, &values);\r
+ XFreePixmap(xDisplay, buf);\r
+\r
+ buf = XCreatePixmap(xDisplay, xBoardWindow,\r
+ squareSize, squareSize, pieceDepth); \r
+ values.foreground = XBlackPixel(xDisplay, xScreen);\r
+ values.background = XWhitePixel(xDisplay, xScreen);\r
+ bufGC = XCreateGC(xDisplay, buf,\r
+ GCForeground | GCBackground, &values);\r
+\r
+ for (piece = WhitePawn; piece <= BlackKing; piece++) {\r
+ /* Begin with empty mask */\r
+ xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,\r
+ squareSize, squareSize, 1);\r
+ XSetFunction(xDisplay, maskGC, GXclear);\r
+ XFillRectangle(xDisplay, xpmMask[piece], maskGC,\r
+ 0, 0, squareSize, squareSize);\r
+ \r
+ /* Take a copy of the piece */\r
+ if (White(piece))\r
+ kind = 0;\r
+ else\r
+ kind = 2;\r
+ XSetFunction(xDisplay, bufGC, GXcopy);\r
+ XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],\r
+ buf, bufGC,\r
+ 0, 0, squareSize, squareSize, 0, 0);\r
+ \r
+ /* XOR the background (light) over the piece */\r
+ XSetFunction(xDisplay, bufGC, GXxor);\r
+ if (useImageSqs)\r
+ XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,\r
+ 0, 0, squareSize, squareSize, 0, 0);\r
+ else {\r
+ XSetForeground(xDisplay, bufGC, lightSquareColor);\r
+ XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);\r
+ }\r
+ \r
+ /* We now have an inverted piece image with the background\r
+ erased. Construct mask by just selecting all the non-zero\r
+ pixels - no need to reconstruct the original image. */\r
+ XSetFunction(xDisplay, maskGC, GXor);\r
+ plane = 1;\r
+ /* Might be quicker to download an XImage and create bitmap\r
+ data from it rather than this N copies per piece, but it\r
+ only takes a fraction of a second and there is a much\r
+ longer delay for loading the pieces. */\r
+ for (n = 0; n < pieceDepth; n ++) {\r
+ XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,\r
+ 0, 0, squareSize, squareSize,\r
+ 0, 0, plane);\r
+ plane = plane << 1;\r
+ }\r
+ }\r
+ /* Clean up */\r
+ XFreePixmap(xDisplay, buf);\r
+ XFreeGC(xDisplay, bufGC);\r
+ XFreeGC(xDisplay, maskGC);\r
+}\r
+\r
+static void\r
+InitAnimState (anim, info)\r
+ AnimState * anim;\r
+ XWindowAttributes * info;\r
+{\r
+ XtGCMask mask;\r
+ XGCValues values;\r
+ \r
+ /* Each buffer is square size, same depth as window */\r
+ anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,\r
+ squareSize, squareSize, info->depth);\r
+ anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,\r
+ squareSize, squareSize, info->depth);\r
+\r
+ /* Create a plain GC for blitting */\r
+ mask = GCForeground | GCBackground | GCFunction |\r
+ GCPlaneMask | GCGraphicsExposures;\r
+ values.foreground = XBlackPixel(xDisplay, xScreen);\r
+ values.background = XWhitePixel(xDisplay, xScreen);\r
+ values.function = GXcopy;\r
+ values.plane_mask = AllPlanes;\r
+ values.graphics_exposures = False;\r
+ anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);\r
+\r
+ /* Piece will be copied from an existing context at\r
+ the start of each new animation/drag. */\r
+ anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);\r
+\r
+ /* Outline will be a read-only copy of an existing */\r
+ anim->outlineGC = None;\r
+}\r
+\r
+static void\r
+CreateAnimVars ()\r
+{\r
+ static int done = 0;\r
+ XWindowAttributes info;\r
+\r
+ if (done) return;\r
+ done = 1;\r
+ XGetWindowAttributes(xDisplay, xBoardWindow, &info);\r
+ \r
+ InitAnimState(&game, &info);\r
+ InitAnimState(&player, &info);\r
+ \r
+ /* For XPM pieces, we need bitmaps to use as masks. */\r
+ if (useImages)\r
+ CreateAnimMasks(info.depth);\r
+}\r
+\r
+#ifndef HAVE_USLEEP\r
+\r
+static Boolean frameWaiting;\r
+\r
+static RETSIGTYPE FrameAlarm (sig)\r
+ int sig;\r
+{\r
+ frameWaiting = False;\r
+ /* In case System-V style signals. Needed?? */\r
+ signal(SIGALRM, FrameAlarm);\r
+}\r
+\r
+static void\r
+FrameDelay (time)\r
+ int time;\r
+{\r
+ struct itimerval delay;\r
+ \r
+ XSync(xDisplay, False);\r
+\r
+ if (time > 0) {\r
+ frameWaiting = True;\r
+ signal(SIGALRM, FrameAlarm);\r
+ delay.it_interval.tv_sec = \r
+ delay.it_value.tv_sec = time / 1000;\r
+ delay.it_interval.tv_usec = \r
+ delay.it_value.tv_usec = (time % 1000) * 1000;\r
+ setitimer(ITIMER_REAL, &delay, NULL);\r
+#if 0\r
+ /* Ugh -- busy-wait! --tpm */\r
+ while (frameWaiting); \r
+#else\r
+ while (frameWaiting) pause();\r
+#endif\r
+ delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;\r
+ delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;\r
+ setitimer(ITIMER_REAL, &delay, NULL);\r
+ }\r
+}\r
+\r
+#else\r
+\r
+static void\r
+FrameDelay (time)\r
+ int time;\r
+{\r
+ XSync(xDisplay, False);\r
+ if (time > 0)\r
+ usleep(time * 1000);\r
+}\r
+\r
+#endif\r
+\r
+/* Convert board position to corner of screen rect and color */\r
+\r
+static void\r
+ScreenSquare(column, row, pt, color)\r
+ int column; int row; XPoint * pt; int * color;\r
+{\r
+ if (flipView) {\r
+ pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
+ pt->y = lineGap + row * (squareSize + lineGap);\r
+ } else {\r
+ pt->x = lineGap + column * (squareSize + lineGap);\r
+ pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
+ }\r
+ *color = SquareColor(row, column);\r
+}\r
+\r
+/* Convert window coords to square */\r
+\r
+static void\r
+BoardSquare(x, y, column, row)\r
+ int x; int y; int * column; int * row;\r
+{\r
+ *column = EventToSquare(x, BOARD_WIDTH);\r
+ if (flipView && *column >= 0)\r
+ *column = BOARD_WIDTH - 1 - *column;\r
+ *row = EventToSquare(y, BOARD_HEIGHT);\r
+ if (!flipView && *row >= 0)\r
+ *row = BOARD_HEIGHT - 1 - *row;\r
+}\r
+\r
+/* Utilities */\r
+\r
+#undef Max /* just in case */\r
+#undef Min\r
+#define Max(a, b) ((a) > (b) ? (a) : (b))\r
+#define Min(a, b) ((a) < (b) ? (a) : (b))\r
+\r
+static void\r
+SetRect(rect, x, y, width, height)\r
+ XRectangle * rect; int x; int y; int width; int height;\r
+{\r
+ rect->x = x;\r
+ rect->y = y;\r
+ rect->width = width;\r
+ rect->height = height;\r
+}\r
+\r
+/* Test if two frames overlap. If they do, return\r
+ intersection rect within old and location of\r
+ that rect within new. */\r
+ \r
+static Boolean\r
+Intersect(old, new, size, area, pt)\r
+ XPoint * old; XPoint * new;\r
+ int size; XRectangle * area; XPoint * pt;\r
+{\r
+ if (old->x > new->x + size || new->x > old->x + size ||\r
+ old->y > new->y + size || new->y > old->y + size) {\r
+ return False;\r
+ } else {\r
+ SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0),\r
+ size - abs(old->x - new->x), size - abs(old->y - new->y));\r
+ pt->x = Max(old->x - new->x, 0);\r
+ pt->y = Max(old->y - new->y, 0);\r
+ return True;\r
+ }\r
+}\r
+\r
+/* For two overlapping frames, return the rect(s)\r
+ in the old that do not intersect with the new. */\r
+ \r
+static void\r
+CalcUpdateRects(old, new, size, update, nUpdates)\r
+ XPoint * old; XPoint * new; int size;\r
+ XRectangle update[]; int * nUpdates;\r
+{\r
+ int count;\r
+\r
+ /* If old = new (shouldn't happen) then nothing to draw */\r
+ if (old->x == new->x && old->y == new->y) {\r
+ *nUpdates = 0;\r
+ return;\r
+ }\r
+ /* Work out what bits overlap. Since we know the rects\r
+ are the same size we don't need a full intersect calc. */\r
+ count = 0;\r
+ /* Top or bottom edge? */\r
+ if (new->y > old->y) {\r
+ SetRect(&(update[count]), old->x, old->y, size, new->y - old->y);\r
+ count ++;\r
+ } else if (old->y > new->y) {\r
+ SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y),\r
+ size, old->y - new->y);\r
+ count ++;\r
+ }\r
+ /* Left or right edge - don't overlap any update calculated above. */\r
+ if (new->x > old->x) {\r
+ SetRect(&(update[count]), old->x, Max(new->y, old->y),\r
+ new->x - old->x, size - abs(new->y - old->y));\r
+ count ++;\r
+ } else if (old->x > new->x) {\r
+ SetRect(&(update[count]), new->x + size, Max(new->y, old->y),\r
+ old->x - new->x, size - abs(new->y - old->y));\r
+ count ++;\r
+ }\r
+ /* Done */\r
+ *nUpdates = count;\r
+}\r
+\r
+/* Generate a series of frame coords from start->mid->finish.\r
+ The movement rate doubles until the half way point is\r
+ reached, then halves back down to the final destination,\r
+ which gives a nice slow in/out effect. The algorithmn\r
+ may seem to generate too many intermediates for short\r
+ moves, but remember that the purpose is to attract the\r
+ viewers attention to the piece about to be moved and\r
+ then to where it ends up. Too few frames would be less\r
+ noticeable. */\r
+\r
+static void\r
+Tween(start, mid, finish, factor, frames, nFrames)\r
+ XPoint * start; XPoint * mid;\r
+ XPoint * finish; int factor;\r
+ XPoint frames[]; int * nFrames;\r
+{\r
+ int fraction, n, count;\r
+\r
+ count = 0;\r
+\r
+ /* Slow in, stepping 1/16th, then 1/8th, ... */\r
+ fraction = 1;\r
+ for (n = 0; n < factor; n++)\r
+ fraction *= 2;\r
+ for (n = 0; n < factor; n++) {\r
+ frames[count].x = start->x + (mid->x - start->x) / fraction;\r
+ frames[count].y = start->y + (mid->y - start->y) / fraction;\r
+ count ++;\r
+ fraction = fraction / 2;\r
+ }\r
+ \r
+ /* Midpoint */\r
+ frames[count] = *mid;\r
+ count ++;\r
+ \r
+ /* Slow out, stepping 1/2, then 1/4, ... */\r
+ fraction = 2;\r
+ for (n = 0; n < factor; n++) {\r
+ frames[count].x = finish->x - (finish->x - mid->x) / fraction;\r
+ frames[count].y = finish->y - (finish->y - mid->y) / fraction;\r
+ count ++;\r
+ fraction = fraction * 2;\r
+ }\r
+ *nFrames = count;\r
+}\r
+\r
+/* Draw a piece on the screen without disturbing what's there */\r
+\r
+static void\r
+SelectGCMask(piece, clip, outline, mask)\r
+ ChessSquare piece; GC * clip; GC * outline; Pixmap * mask;\r
+{\r
+ GC source;\r
+\r
+ /* Bitmap for piece being moved. */\r
+ if (appData.monoMode) {\r
+ *mask = *pieceToSolid(piece);\r
+ } else if (useImages) {\r
+#if HAVE_LIBXPM\r
+ *mask = xpmMask[piece];\r
+#else\r
+ *mask = ximMaskPm[piece%(int)BlackPawn];\r
+#endif\r
+ } else {\r
+ *mask = *pieceToSolid(piece);\r
+ }\r
+\r
+ /* GC for piece being moved. Square color doesn't matter, but\r
+ since it gets modified we make a copy of the original. */\r
+ if (White(piece)) {\r
+ if (appData.monoMode)\r
+ source = bwPieceGC;\r
+ else\r
+ source = wlPieceGC;\r
+ } else {\r
+ if (appData.monoMode)\r
+ source = wbPieceGC;\r
+ else\r
+ source = blPieceGC;\r
+ }\r
+ XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);\r
+ \r
+ /* Outline only used in mono mode and is not modified */\r
+ if (White(piece))\r
+ *outline = bwPieceGC;\r
+ else\r
+ *outline = wbPieceGC;\r
+}\r
+\r
+static void\r
+OverlayPiece(piece, clip, outline, dest)\r
+ ChessSquare piece; GC clip; GC outline; Drawable dest;\r
+{\r
+ int kind;\r
+ \r
+ if (!useImages) {\r
+ /* Draw solid rectangle which will be clipped to shape of piece */\r
+ XFillRectangle(xDisplay, dest, clip,\r
+ 0, 0, squareSize, squareSize);\r
+ if (appData.monoMode)\r
+ /* Also draw outline in contrasting color for black\r
+ on black / white on white cases */\r
+ XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,\r
+ 0, 0, squareSize, squareSize, 0, 0, 1);\r
+ } else {\r
+ /* Copy the piece */\r
+ if (White(piece))\r
+ kind = 0;\r
+ else\r
+ kind = 2;\r
+ XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],\r
+ dest, clip,\r
+ 0, 0, squareSize, squareSize,\r
+ 0, 0); \r
+ }\r
+}\r
+\r
+/* Animate the movement of a single piece */\r
+\r
+static void \r
+BeginAnimation(anim, piece, startColor, start)\r
+ AnimState *anim;\r
+ ChessSquare piece;\r
+ int startColor;\r
+ XPoint * start;\r
+{\r
+ Pixmap mask;\r
+ \r
+ /* The old buffer is initialised with the start square (empty) */\r
+ BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);\r
+ anim->prevFrame = *start;\r
+ \r
+ /* The piece will be drawn using its own bitmap as a matte */\r
+ SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);\r
+ XSetClipMask(xDisplay, anim->pieceGC, mask);\r
+}\r
+\r
+static void\r
+AnimationFrame(anim, frame, piece)\r
+ AnimState *anim;\r
+ XPoint *frame;\r
+ ChessSquare piece;\r
+{\r
+ XRectangle updates[4];\r
+ XRectangle overlap;\r
+ XPoint pt;\r
+ int count, i;\r
+ \r
+ /* Save what we are about to draw into the new buffer */\r
+ XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,\r
+ frame->x, frame->y, squareSize, squareSize,\r
+ 0, 0);\r
+ \r
+ /* Erase bits of the previous frame */\r
+ if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {\r
+ /* Where the new frame overlapped the previous,\r
+ the contents in newBuf are wrong. */\r
+ XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,\r
+ overlap.x, overlap.y,\r
+ overlap.width, overlap.height,\r
+ pt.x, pt.y);\r
+ /* Repaint the areas in the old that don't overlap new */\r
+ CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);\r
+ for (i = 0; i < count; i++)\r
+ XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,\r
+ updates[i].x - anim->prevFrame.x,\r
+ updates[i].y - anim->prevFrame.y,\r
+ updates[i].width, updates[i].height,\r
+ updates[i].x, updates[i].y);\r
+ } else {\r
+ /* Easy when no overlap */\r
+ XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,\r
+ 0, 0, squareSize, squareSize,\r
+ anim->prevFrame.x, anim->prevFrame.y);\r
+ }\r
+\r
+ /* Save this frame for next time round */\r
+ XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,\r
+ 0, 0, squareSize, squareSize,\r
+ 0, 0);\r
+ anim->prevFrame = *frame;\r
+ \r
+ /* Draw piece over original screen contents, not current,\r
+ and copy entire rect. Wipes out overlapping piece images. */\r
+ OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);\r
+ XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,\r
+ 0, 0, squareSize, squareSize,\r
+ frame->x, frame->y);\r
+}\r
+\r
+static void\r
+EndAnimation (anim, finish)\r
+ AnimState *anim;\r
+ XPoint *finish;\r
+{\r
+ XRectangle updates[4];\r
+ XRectangle overlap;\r
+ XPoint pt;\r
+ int count, i;\r
+\r
+ /* The main code will redraw the final square, so we\r
+ only need to erase the bits that don't overlap. */\r
+ if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {\r
+ CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);\r
+ for (i = 0; i < count; i++)\r
+ XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,\r
+ updates[i].x - anim->prevFrame.x,\r
+ updates[i].y - anim->prevFrame.y,\r
+ updates[i].width, updates[i].height,\r
+ updates[i].x, updates[i].y);\r
+ } else {\r
+ XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,\r
+ 0, 0, squareSize, squareSize,\r
+ anim->prevFrame.x, anim->prevFrame.y);\r
+ }\r
+}\r
+\r
+static void\r
+FrameSequence(anim, piece, startColor, start, finish, frames, nFrames)\r
+ AnimState *anim;\r
+ ChessSquare piece; int startColor;\r
+ XPoint * start; XPoint * finish;\r
+ XPoint frames[]; int nFrames;\r
+{\r
+ int n;\r
+\r
+ BeginAnimation(anim, piece, startColor, start);\r
+ for (n = 0; n < nFrames; n++) {\r
+ AnimationFrame(anim, &(frames[n]), piece);\r
+ FrameDelay(appData.animSpeed);\r
+ }\r
+ EndAnimation(anim, finish);\r
+}\r
+\r
+/* Main control logic for deciding what to animate and how */\r
+\r
+void\r
+AnimateMove(board, fromX, fromY, toX, toY)\r
+ Board board;\r
+ int fromX;\r
+ int fromY;\r
+ int toX;\r
+ int toY;\r
+{\r
+ ChessSquare piece;\r
+ int hop;\r
+ XPoint start, finish, mid;\r
+ XPoint frames[kFactor * 2 + 1];\r
+ int nFrames, startColor, endColor;\r
+\r
+ /* Are we animating? */\r
+ if (!appData.animate || appData.blindfold)\r
+ return;\r
+\r
+ if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;\r
+ piece = board[fromY][fromX];\r
+ if (piece >= EmptySquare) return;\r
+\r
+#if DONT_HOP\r
+ hop = FALSE;\r
+#else\r
+ hop = (piece == WhiteKnight || piece == BlackKnight);\r
+#endif\r
+\r
+ if (appData.debugMode) {\r
+ printf("AnimateMove: piece %d %s from %d,%d to %d,%d \n",\r
+ piece, hop ? "hops" : "slides", fromX, fromY, toX, toY);\r
+ }\r
+\r
+ ScreenSquare(fromX, fromY, &start, &startColor);\r
+ ScreenSquare(toX, toY, &finish, &endColor);\r
+\r
+ if (hop) {\r
+ /* Knight: make diagonal movement then straight */\r
+ if (abs(toY - fromY) < abs(toX - fromX)) {\r
+ mid.x = start.x + (finish.x - start.x) / 2;\r
+ mid.y = finish.y;\r
+ } else {\r
+ mid.x = finish.x;\r
+ mid.y = start.y + (finish.y - start.y) / 2;\r
+ }\r
+ } else {\r
+ mid.x = start.x + (finish.x - start.x) / 2;\r
+ mid.y = start.y + (finish.y - start.y) / 2;\r
+ }\r
+ \r
+ /* Don't use as many frames for very short moves */\r
+ if (abs(toY - fromY) + abs(toX - fromX) <= 2)\r
+ Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);\r
+ else\r
+ Tween(&start, &mid, &finish, kFactor, frames, &nFrames);\r
+ FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);\r
+ \r
+ /* Be sure end square is redrawn */\r
+ damage[toY][toX] = True;\r
+}\r
+\r
+static void\r
+DragPieceBegin(x, y)\r
+ int x; int y;\r
+{\r
+ int boardX, boardY, color;\r
+ XPoint corner;\r
+\r
+ /* Are we animating? */\r
+ if (!appData.animateDragging || appData.blindfold)\r
+ return;\r
+ \r
+ /* Figure out which square we start in and the\r
+ mouse position relative to top left corner. */\r
+ BoardSquare(x, y, &boardX, &boardY);\r
+ player.startBoardX = boardX;\r
+ player.startBoardY = boardY;\r
+ ScreenSquare(boardX, boardY, &corner, &color);\r
+ player.startSquare = corner;\r
+ player.startColor = color;\r
+#if 0\r
+ /* Start from exactly where the piece is. This can be confusing\r
+ if you start dragging far from the center of the square; most\r
+ or all of the piece can be over a different square from the one\r
+ the mouse pointer is in. */\r
+ player.mouseDelta.x = x - corner.x;\r
+ player.mouseDelta.y = y - corner.y;\r
+#else\r
+ /* As soon as we start dragging, the piece will jump slightly to\r
+ be centered over the mouse pointer. */\r
+ player.mouseDelta.x = squareSize/2;\r
+ player.mouseDelta.y = squareSize/2;\r
+#endif\r
+ /* Initialise animation */\r
+ player.dragPiece = PieceForSquare(boardX, boardY);\r
+ /* Sanity check */\r
+ if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {\r
+ player.dragActive = True;\r
+ BeginAnimation(&player, player.dragPiece, color, &corner);\r
+ /* Mark this square as needing to be redrawn. Note that\r
+ we don't remove the piece though, since logically (ie\r
+ as seen by opponent) the move hasn't been made yet. */\r
+ damage[boardY][boardX] = True;\r
+ } else {\r
+ player.dragActive = False;\r
+ }\r
+}\r
+\r
+static void\r
+DragPieceMove(x, y)\r
+ int x; int y;\r
+{\r
+ XPoint corner;\r
+\r
+ /* Are we animating? */\r
+ if (!appData.animateDragging || appData.blindfold)\r
+ return;\r
+ \r
+ /* Sanity check */\r
+ if (! player.dragActive)\r
+ return;\r
+ /* Move piece, maintaining same relative position\r
+ of mouse within square */\r
+ corner.x = x - player.mouseDelta.x;\r
+ corner.y = y - player.mouseDelta.y;\r
+ AnimationFrame(&player, &corner, player.dragPiece);\r
+#if HIGHDRAG\r
+ if (appData.highlightDragging) {\r
+ int boardX, boardY;\r
+ BoardSquare(x, y, &boardX, &boardY);\r
+ SetHighlights(fromX, fromY, boardX, boardY);\r
+ }\r
+#endif\r
+}\r
+\r
+static void\r
+DragPieceEnd(x, y)\r
+ int x; int y;\r
+{\r
+ int boardX, boardY, color;\r
+ XPoint corner;\r
+\r
+ /* Are we animating? */\r
+ if (!appData.animateDragging || appData.blindfold)\r
+ return;\r
+ \r
+ /* Sanity check */\r
+ if (! player.dragActive)\r
+ return;\r
+ /* Last frame in sequence is square piece is\r
+ placed on, which may not match mouse exactly. */\r
+ BoardSquare(x, y, &boardX, &boardY);\r
+ ScreenSquare(boardX, boardY, &corner, &color);\r
+ EndAnimation(&player, &corner);\r
+\r
+ /* Be sure end square is redrawn */\r
+ damage[boardY][boardX] = True;\r
+\r
+ /* This prevents weird things happening with fast successive\r
+ clicks which on my Sun at least can cause motion events\r
+ without corresponding press/release. */\r
+ player.dragActive = False;\r
+}\r
+\r
+/* Handle expose event while piece being dragged */\r
+\r
+static void\r
+DrawDragPiece ()\r
+{\r
+ if (!player.dragActive || appData.blindfold)\r
+ return;\r
+\r
+ /* What we're doing: logically, the move hasn't been made yet,\r
+ so the piece is still in it's original square. But visually\r
+ it's being dragged around the board. So we erase the square\r
+ that the piece is on and draw it at the last known drag point. */\r
+ BlankSquare(player.startSquare.x, player.startSquare.y,\r
+ player.startColor, EmptySquare, xBoardWindow);\r
+ AnimationFrame(&player, &player.prevFrame, player.dragPiece);\r
+ damage[player.startBoardY][player.startBoardX] = TRUE;\r
+}\r
+\r
+void\r
+SetProgramStats( FrontEndProgramStats * stats )\r
+{\r
+ // [HR] TODO\r
+}\r