2 * xboard.c -- X front end for XBoard
\r
3 * $Id: xboard.c,v 2.2 2003/11/06 07:22:14 mann Exp $
\r
5 * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
\r
6 * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.
\r
8 * The following terms apply to Digital Equipment Corporation's copyright
\r
9 * interest in XBoard:
\r
10 * ------------------------------------------------------------------------
\r
11 * All Rights Reserved
\r
13 * Permission to use, copy, modify, and distribute this software and its
\r
14 * documentation for any purpose and without fee is hereby granted,
\r
15 * provided that the above copyright notice appear in all copies and that
\r
16 * both that copyright notice and this permission notice appear in
\r
17 * supporting documentation, and that the name of Digital not be
\r
18 * used in advertising or publicity pertaining to distribution of the
\r
19 * software without specific, written prior permission.
\r
21 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
\r
22 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
\r
23 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
\r
24 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
\r
25 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
\r
26 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
\r
28 * ------------------------------------------------------------------------
\r
30 * The following terms apply to the enhanced version of XBoard distributed
\r
31 * by the Free Software Foundation:
\r
32 * ------------------------------------------------------------------------
\r
33 * This program is free software; you can redistribute it and/or modify
\r
34 * it under the terms of the GNU General Public License as published by
\r
35 * the Free Software Foundation; either version 2 of the License, or
\r
36 * (at your option) any later version.
\r
38 * This program is distributed in the hope that it will be useful,
\r
39 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
41 * GNU General Public License for more details.
\r
43 * You should have received a copy of the GNU General Public License
\r
44 * along with this program; if not, write to the Free Software
\r
45 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
46 * ------------------------------------------------------------------------
\r
48 * See the file ChangeLog for a revision history.
\r
57 #include <sys/types.h>
\r
58 #include <sys/stat.h>
\r
62 # if HAVE_SYS_SOCKET_H
\r
63 # include <sys/socket.h>
\r
64 # include <netinet/in.h>
\r
66 # else /* not HAVE_SYS_SOCKET_H */
\r
67 # if HAVE_LAN_SOCKET_H
\r
68 # include <lan/socket.h>
\r
69 # include <lan/in.h>
\r
70 # include <lan/netdb.h>
\r
71 # else /* not HAVE_LAN_SOCKET_H */
\r
72 # define OMIT_SOCKETS 1
\r
73 # endif /* not HAVE_LAN_SOCKET_H */
\r
74 # endif /* not HAVE_SYS_SOCKET_H */
\r
75 #endif /* !OMIT_SOCKETS */
\r
78 # include <stdlib.h>
\r
79 # include <string.h>
\r
80 #else /* not STDC_HEADERS */
\r
81 extern char *getenv();
\r
83 # include <string.h>
\r
84 # else /* not HAVE_STRING_H */
\r
85 # include <strings.h>
\r
86 # endif /* not HAVE_STRING_H */
\r
87 #endif /* not STDC_HEADERS */
\r
89 #if HAVE_SYS_FCNTL_H
\r
90 # include <sys/fcntl.h>
\r
91 #else /* not HAVE_SYS_FCNTL_H */
\r
94 # endif /* HAVE_FCNTL_H */
\r
95 #endif /* not HAVE_SYS_FCNTL_H */
\r
97 #if HAVE_SYS_SYSTEMINFO_H
\r
98 # include <sys/systeminfo.h>
\r
99 #endif /* HAVE_SYS_SYSTEMINFO_H */
\r
101 #if TIME_WITH_SYS_TIME
\r
102 # include <sys/time.h>
\r
105 # if HAVE_SYS_TIME_H
\r
106 # include <sys/time.h>
\r
113 # include <unistd.h>
\r
116 #if HAVE_SYS_WAIT_H
\r
117 # include <sys/wait.h>
\r
121 # include <dirent.h>
\r
122 # define NAMLEN(dirent) strlen((dirent)->d_name)
\r
123 # define HAVE_DIR_STRUCT
\r
125 # define dirent direct
\r
126 # define NAMLEN(dirent) (dirent)->d_namlen
\r
127 # if HAVE_SYS_NDIR_H
\r
128 # include <sys/ndir.h>
\r
129 # define HAVE_DIR_STRUCT
\r
131 # if HAVE_SYS_DIR_H
\r
132 # include <sys/dir.h>
\r
133 # define HAVE_DIR_STRUCT
\r
137 # define HAVE_DIR_STRUCT
\r
141 #include <X11/Intrinsic.h>
\r
142 #include <X11/StringDefs.h>
\r
143 #include <X11/Shell.h>
\r
144 #include <X11/cursorfont.h>
\r
145 #include <X11/Xatom.h>
\r
147 #include <X11/Xaw3d/Dialog.h>
\r
148 #include <X11/Xaw3d/Form.h>
\r
149 #include <X11/Xaw3d/List.h>
\r
150 #include <X11/Xaw3d/Label.h>
\r
151 #include <X11/Xaw3d/SimpleMenu.h>
\r
152 #include <X11/Xaw3d/SmeBSB.h>
\r
153 #include <X11/Xaw3d/SmeLine.h>
\r
154 #include <X11/Xaw3d/Box.h>
\r
155 #include <X11/Xaw3d/MenuButton.h>
\r
156 #include <X11/Xaw3d/Text.h>
\r
157 #include <X11/Xaw3d/AsciiText.h>
\r
159 #include <X11/Xaw/Dialog.h>
\r
160 #include <X11/Xaw/Form.h>
\r
161 #include <X11/Xaw/List.h>
\r
162 #include <X11/Xaw/Label.h>
\r
163 #include <X11/Xaw/SimpleMenu.h>
\r
164 #include <X11/Xaw/SmeBSB.h>
\r
165 #include <X11/Xaw/SmeLine.h>
\r
166 #include <X11/Xaw/Box.h>
\r
167 #include <X11/Xaw/MenuButton.h>
\r
168 #include <X11/Xaw/Text.h>
\r
169 #include <X11/Xaw/AsciiText.h>
\r
172 // [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
\r
173 #include "common.h"
\r
176 #include <X11/xpm.h>
\r
177 #include "pixmaps/pixmaps.h"
\r
178 #define IMAGE_EXT "xpm"
\r
180 #define IMAGE_EXT "xim"
\r
181 #include "bitmaps/bitmaps.h"
\r
184 #include "bitmaps/icon_white.bm"
\r
185 #include "bitmaps/icon_black.bm"
\r
186 #include "bitmaps/checkmark.bm"
\r
188 #include "frontend.h"
\r
189 #include "backend.h"
\r
191 #include "xboard.h"
\r
192 #include "childio.h"
\r
193 #include "xgamelist.h"
\r
194 #include "xhistory.h"
\r
195 #include "xedittags.h"
\r
196 #include "gettext.h"
\r
198 // must be moved to xengineoutput.h
\r
200 void EngineOutputProc P((Widget w, XEvent *event,
\r
201 String *prms, Cardinal *nprms));
\r
203 void EngineOutputPopDown();
\r
207 #ifndef HAVE_USLEEP
\r
208 #define HAVE_USLEEP
\r
210 #define usleep(t) _sleep2(((t)+500)/1000)
\r
214 # define _(s) gettext (s)
\r
215 # define N_(s) gettext_noop (s)
\r
231 int main P((int argc, char **argv));
\r
232 RETSIGTYPE CmailSigHandler P((int sig));
\r
233 RETSIGTYPE IntSigHandler P((int sig));
\r
234 void CreateGCs P((void));
\r
235 void CreateXIMPieces P((void));
\r
236 void CreateXPMPieces P((void));
\r
237 void CreatePieces P((void));
\r
238 void CreatePieceMenus P((void));
\r
239 Widget CreateMenuBar P((Menu *mb));
\r
240 Widget CreateButtonBar P ((MenuItem *mi));
\r
241 char *FindFont P((char *pattern, int targetPxlSize));
\r
242 void PieceMenuPopup P((Widget w, XEvent *event,
\r
243 String *params, Cardinal *num_params));
\r
244 static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
\r
245 static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
\r
246 void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
\r
247 u_int wreq, u_int hreq));
\r
248 void CreateGrid P((void));
\r
249 int EventToSquare P((int x, int limit));
\r
250 void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
\r
251 void EventProc P((Widget widget, caddr_t unused, XEvent *event));
\r
252 void HandleUserMove P((Widget w, XEvent *event,
\r
253 String *prms, Cardinal *nprms));
\r
254 void AnimateUserMove P((Widget w, XEvent * event,
\r
255 String * params, Cardinal * nParams));
\r
256 void WhiteClock P((Widget w, XEvent *event,
\r
257 String *prms, Cardinal *nprms));
\r
258 void BlackClock P((Widget w, XEvent *event,
\r
259 String *prms, Cardinal *nprms));
\r
260 void DrawPositionProc P((Widget w, XEvent *event,
\r
261 String *prms, Cardinal *nprms));
\r
262 void XDrawPosition P((Widget w, /*Boolean*/int repaint,
\r
264 void CommentPopUp P((char *title, char *label));
\r
265 void CommentPopDown P((void));
\r
266 void CommentCallback P((Widget w, XtPointer client_data,
\r
267 XtPointer call_data));
\r
268 void ICSInputBoxPopUp P((void));
\r
269 void ICSInputBoxPopDown P((void));
\r
270 void FileNamePopUp P((char *label, char *def,
\r
271 FileProc proc, char *openMode));
\r
272 void FileNamePopDown P((void));
\r
273 void FileNameCallback P((Widget w, XtPointer client_data,
\r
274 XtPointer call_data));
\r
275 void FileNameAction P((Widget w, XEvent *event,
\r
276 String *prms, Cardinal *nprms));
\r
277 void AskQuestionReplyAction P((Widget w, XEvent *event,
\r
278 String *prms, Cardinal *nprms));
\r
279 void AskQuestionProc P((Widget w, XEvent *event,
\r
280 String *prms, Cardinal *nprms));
\r
281 void AskQuestionPopDown P((void));
\r
282 void PromotionPopUp P((void));
\r
283 void PromotionPopDown P((void));
\r
284 void PromotionCallback P((Widget w, XtPointer client_data,
\r
285 XtPointer call_data));
\r
286 void EditCommentPopDown P((void));
\r
287 void EditCommentCallback P((Widget w, XtPointer client_data,
\r
288 XtPointer call_data));
\r
289 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
\r
290 void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
291 void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
292 void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
\r
294 void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
\r
296 void ReloadGameProc P((Widget w, XEvent *event, String *prms,
\r
298 void LoadPositionProc P((Widget w, XEvent *event,
\r
299 String *prms, Cardinal *nprms));
\r
300 void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
\r
302 void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
\r
304 void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
\r
306 void CopyPositionProc P((Widget w, XEvent *event, String *prms,
\r
308 void PastePositionProc P((Widget w, XEvent *event, String *prms,
\r
310 void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
311 void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
312 void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
313 void SavePositionProc P((Widget w, XEvent *event,
\r
314 String *prms, Cardinal *nprms));
\r
315 void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
316 void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
\r
318 void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
319 void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
320 void MachineBlackProc P((Widget w, XEvent *event, String *prms,
\r
322 void MachineWhiteProc P((Widget w, XEvent *event,
\r
323 String *prms, Cardinal *nprms));
\r
324 void AnalyzeModeProc P((Widget w, XEvent *event,
\r
325 String *prms, Cardinal *nprms));
\r
326 void AnalyzeFileProc P((Widget w, XEvent *event,
\r
327 String *prms, Cardinal *nprms));
\r
328 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
\r
330 void IcsClientProc P((Widget w, XEvent *event, String *prms,
\r
332 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
333 void EditPositionProc P((Widget w, XEvent *event,
\r
334 String *prms, Cardinal *nprms));
\r
335 void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
336 void EditCommentProc P((Widget w, XEvent *event,
\r
337 String *prms, Cardinal *nprms));
\r
338 void IcsInputBoxProc P((Widget w, XEvent *event,
\r
339 String *prms, Cardinal *nprms));
\r
340 void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
341 void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
342 void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
343 void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
344 void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
345 void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
346 void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
347 void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
348 void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
349 void StopObservingProc P((Widget w, XEvent *event, String *prms,
\r
351 void StopExaminingProc P((Widget w, XEvent *event, String *prms,
\r
353 void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
354 void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
355 void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
356 void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
357 void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
358 void TruncateGameProc P((Widget w, XEvent *event, String *prms,
\r
360 void RetractMoveProc P((Widget w, XEvent *event, String *prms,
\r
362 void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
363 void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
\r
365 void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
\r
367 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
\r
369 void AutocommProc P((Widget w, XEvent *event, String *prms,
\r
371 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
372 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
373 void AutobsProc P((Widget w, XEvent *event, String *prms,
\r
375 void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
376 void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
377 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
378 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
\r
380 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
381 void GetMoveListProc P((Widget w, XEvent *event, String *prms,
\r
383 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
\r
385 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
\r
387 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
388 void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
389 void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
\r
391 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
\r
393 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
\r
395 void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
\r
397 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
\r
399 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
400 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
401 void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
\r
403 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
\r
405 void HideThinkingProc P((Widget w, XEvent *event, String *prms,
\r
407 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
\r
409 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
410 void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
411 void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
412 void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
413 void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
414 void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
415 void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
416 void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
417 void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
418 void DisplayMove P((int moveNumber));
\r
419 void DisplayTitle P((char *title));
\r
420 void ICSInitScript P((void));
\r
421 int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
\r
422 void ErrorPopUp P((char *title, char *text, int modal));
\r
423 void ErrorPopDown P((void));
\r
424 static char *ExpandPathName P((char *path));
\r
425 static void CreateAnimVars P((void));
\r
426 static void DragPieceBegin P((int x, int y));
\r
427 static void DragPieceMove P((int x, int y));
\r
428 static void DragPieceEnd P((int x, int y));
\r
429 static void DrawDragPiece P((void));
\r
430 char *ModeToWidgetName P((GameMode mode));
\r
431 void EngineOutputUpdate( FrontEndProgramStats * stats );
\r
432 void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
433 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
434 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
435 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
436 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
437 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
438 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
\r
439 void ShufflePopDown P(());
\r
440 void EnginePopDown P(());
\r
441 void UciPopDown P(());
\r
442 void TimeControlPopDown P(());
\r
443 void NewVariantPopDown P(());
\r
444 void SettingsPopDown P(());
\r
446 * XBoard depends on Xt R4 or higher
\r
448 int xtVersion = XtSpecificationRelease;
\r
452 Window xBoardWindow;
\r
453 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
\r
454 jailSquareColor, highlightSquareColor, premoveHighlightColor;
\r
455 GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
\r
456 bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
\r
457 wjPieceGC, bjPieceGC, prelineGC, countGC;
\r
458 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
\r
459 Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
\r
460 whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
\r
461 commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
\r
462 menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
\r
463 ICSInputShell, fileNameShell, askQuestionShell;
\r
464 XSegment gridSegments[(BOARD_SIZE + 1) * 2];
\r
465 XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
\r
466 Font clockFontID, coordFontID, countFontID;
\r
467 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
\r
468 XtAppContext appContext;
\r
470 char *oldICSInteractionTitle;
\r
473 char *fileOpenMode;
\r
474 char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
\r
476 Position commentX = -1, commentY = -1;
\r
477 Dimension commentW, commentH;
\r
479 int squareSize, smallLayout = 0, tinyLayout = 0,
\r
480 marginW, marginH, // [HGM] for run-time resizing
\r
481 fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
\r
482 ICSInputBoxUp = False, askQuestionUp = False,
\r
483 filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
\r
484 editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
\r
485 Pixel timerForegroundPixel, timerBackgroundPixel;
\r
486 Pixel buttonForegroundPixel, buttonBackgroundPixel;
\r
487 char *chessDir, *programName, *programVersion,
\r
488 *gameCopyFilename, *gamePasteFilename;
\r
492 Pixmap pieceBitmap[2][(int)BlackPawn];
\r
493 Pixmap xpmPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */
\r
494 Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
\r
495 int useImages, useImageSqs;
\r
496 XImage *ximPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD */
\r
497 Pixmap ximMaskPm[(int)BlackPawn]; /* clipmasks, used for XIM pieces */
\r
498 XImage *ximLightSquare, *ximDarkSquare;
\r
501 #define pieceToSolid(piece) &pieceBitmap[SOLID][((int)(piece)) % (int)BlackPawn]
\r
502 #define pieceToOutline(piece) &pieceBitmap[OUTLINE][((int)(piece)) % (int)BlackPawn]
\r
504 #define White(piece) ((int)(piece) < (int)BlackPawn)
\r
506 /* Variables for doing smooth animation. This whole thing
\r
507 would be much easier if the board was double-buffered,
\r
508 but that would require a fairly major rewrite. */
\r
513 GC blitGC, pieceGC, outlineGC;
\r
514 XPoint startSquare, prevFrame, mouseDelta;
\r
517 Boolean dragActive;
\r
518 int startBoardX, startBoardY;
\r
521 /* There can be two pieces being animated at once: a player
\r
522 can begin dragging a piece before the remote opponent has moved. */
\r
524 static AnimState game, player;
\r
526 /* Bitmaps for use as masks when drawing XPM pieces.
\r
527 Need one for each black and white piece. */
\r
528 static Pixmap xpmMask[BlackKing + 1];
\r
530 /* This magic number is the number of intermediate frames used
\r
531 in each half of the animation. For short moves it's reduced
\r
532 by 1. The total number of frames will be factor * 2 + 1. */
\r
535 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
\r
537 MenuItem fileMenu[] = {
\r
538 {N_("New Game"), ResetProc},
\r
539 {N_("New Shuffle Game ..."), ShuffleMenuProc},
\r
540 {N_("New Variant ..."), NewVariantProc}, // [HGM] variant: not functional yet
\r
541 {"----", NothingProc},
\r
542 {N_("Load Game"), LoadGameProc},
\r
543 {N_("Load Next Game"), LoadNextGameProc},
\r
544 {N_("Load Previous Game"), LoadPrevGameProc},
\r
545 {N_("Reload Same Game"), ReloadGameProc},
\r
546 {N_("Save Game"), SaveGameProc},
\r
547 {"----", NothingProc},
\r
548 {N_("Copy Game"), CopyGameProc},
\r
549 {N_("Paste Game"), PasteGameProc},
\r
550 {"----", NothingProc},
\r
551 {N_("Load Position"), LoadPositionProc},
\r
552 {N_("Load Next Position"), LoadNextPositionProc},
\r
553 {N_("Load Previous Position"), LoadPrevPositionProc},
\r
554 {N_("Reload Same Position"), ReloadPositionProc},
\r
555 {N_("Save Position"), SavePositionProc},
\r
556 {"----", NothingProc},
\r
557 {N_("Copy Position"), CopyPositionProc},
\r
558 {N_("Paste Position"), PastePositionProc},
\r
559 {"----", NothingProc},
\r
560 {N_("Mail Move"), MailMoveProc},
\r
561 {N_("Reload CMail Message"), ReloadCmailMsgProc},
\r
562 {"----", NothingProc},
\r
563 {N_("Exit"), QuitProc},
\r
567 MenuItem modeMenu[] = {
\r
568 {N_("Machine White"), MachineWhiteProc},
\r
569 {N_("Machine Black"), MachineBlackProc},
\r
570 {N_("Two Machines"), TwoMachinesProc},
\r
571 {N_("Analysis Mode"), AnalyzeModeProc},
\r
572 {N_("Analyze File"), AnalyzeFileProc },
\r
573 {N_("ICS Client"), IcsClientProc},
\r
574 {N_("Edit Game"), EditGameProc},
\r
575 {N_("Edit Position"), EditPositionProc},
\r
576 {N_("Training"), TrainingProc},
\r
577 {"----", NothingProc},
\r
578 {N_("Show Engine Output"), EngineOutputProc},
\r
579 {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
\r
580 {N_("Show Game List"), ShowGameListProc},
\r
581 {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
\r
582 {"----", NothingProc},
\r
583 {N_("Edit Tags"), EditTagsProc},
\r
584 {N_("Edit Comment"), EditCommentProc},
\r
585 {N_("ICS Input Box"), IcsInputBoxProc},
\r
586 {N_("Pause"), PauseProc},
\r
590 MenuItem actionMenu[] = {
\r
591 {N_("Accept"), AcceptProc},
\r
592 {N_("Decline"), DeclineProc},
\r
593 {N_("Rematch"), RematchProc},
\r
594 {"----", NothingProc},
\r
595 {N_("Call Flag"), CallFlagProc},
\r
596 {N_("Draw"), DrawProc},
\r
597 {N_("Adjourn"), AdjournProc},
\r
598 {N_("Abort"), AbortProc},
\r
599 {N_("Resign"), ResignProc},
\r
600 {"----", NothingProc},
\r
601 {N_("Stop Observing"), StopObservingProc},
\r
602 {N_("Stop Examining"), StopExaminingProc},
\r
606 MenuItem stepMenu[] = {
\r
607 {N_("Backward"), BackwardProc},
\r
608 {N_("Forward"), ForwardProc},
\r
609 {N_("Back to Start"), ToStartProc},
\r
610 {N_("Forward to End"), ToEndProc},
\r
611 {N_("Revert"), RevertProc},
\r
612 {N_("Truncate Game"), TruncateGameProc},
\r
613 {"----", NothingProc},
\r
614 {N_("Move Now"), MoveNowProc},
\r
615 {N_("Retract Move"), RetractMoveProc},
\r
619 MenuItem optionsMenu[] = {
\r
620 {N_("Flip View"), FlipViewProc},
\r
621 {"----", NothingProc},
\r
622 {N_("Adjudications ..."), EngineMenuProc},
\r
623 {N_("General Settings ..."), UciMenuProc},
\r
624 {N_("Engine #1 Settings ..."), FirstSettingsProc},
\r
625 {N_("Engine #2 Settings ..."), SecondSettingsProc},
\r
626 {N_("Time Control ..."), TimeControlProc},
\r
627 {"----", NothingProc},
\r
628 {N_("Always Queen"), AlwaysQueenProc},
\r
629 {N_("Animate Dragging"), AnimateDraggingProc},
\r
630 {N_("Animate Moving"), AnimateMovingProc},
\r
631 {N_("Auto Comment"), AutocommProc},
\r
632 {N_("Auto Flag"), AutoflagProc},
\r
633 {N_("Auto Flip View"), AutoflipProc},
\r
634 {N_("Auto Observe"), AutobsProc},
\r
635 {N_("Auto Raise Board"), AutoraiseProc},
\r
636 {N_("Auto Save"), AutosaveProc},
\r
637 {N_("Blindfold"), BlindfoldProc},
\r
638 {N_("Flash Moves"), FlashMovesProc},
\r
639 {N_("Get Move List"), GetMoveListProc},
\r
641 {N_("Highlight Dragging"), HighlightDraggingProc},
\r
643 {N_("Highlight Last Move"), HighlightLastMoveProc},
\r
644 {N_("Move Sound"), MoveSoundProc},
\r
645 {N_("ICS Alarm"), IcsAlarmProc},
\r
646 {N_("Old Save Style"), OldSaveStyleProc},
\r
647 {N_("Periodic Updates"), PeriodicUpdatesProc},
\r
648 {N_("Ponder Next Move"), PonderNextMoveProc},
\r
649 {N_("Popup Exit Message"), PopupExitMessageProc},
\r
650 {N_("Popup Move Errors"), PopupMoveErrorsProc},
\r
651 {N_("Premove"), PremoveProc},
\r
652 {N_("Quiet Play"), QuietPlayProc},
\r
653 {N_("Show Coords"), ShowCoordsProc},
\r
654 {N_("Hide Thinking"), HideThinkingProc},
\r
655 {N_("Test Legality"), TestLegalityProc},
\r
659 MenuItem helpMenu[] = {
\r
660 {N_("Info XBoard"), InfoProc},
\r
661 {N_("Man XBoard"), ManProc},
\r
662 {"----", NothingProc},
\r
663 {N_("Hint"), HintProc},
\r
664 {N_("Book"), BookProc},
\r
665 {"----", NothingProc},
\r
666 {N_("About XBoard"), AboutProc},
\r
671 {N_("File"), fileMenu},
\r
672 {N_("Mode"), modeMenu},
\r
673 {N_("Action"), actionMenu},
\r
674 {N_("Step"), stepMenu},
\r
675 {N_("Options"), optionsMenu},
\r
676 {N_("Help"), helpMenu},
\r
680 #define PAUSE_BUTTON N_("P")
\r
681 MenuItem buttonBar[] = {
\r
682 {"<<", ToStartProc},
\r
683 {"<", BackwardProc},
\r
684 {PAUSE_BUTTON, PauseProc},
\r
685 {">", ForwardProc},
\r
690 #define PIECE_MENU_SIZE 11
\r
691 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
\r
692 { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
\r
693 N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
\r
694 { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
\r
695 N_("Queen"), N_("King"), "----", N_("Empty square"), N_("Clear board") },
\r
697 /* must be in same order as PieceMenuStrings! */
\r
698 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
\r
699 { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
\r
700 WhiteRook, WhiteQueen, WhiteKing,
\r
701 (ChessSquare) 0, EmptySquare, ClearBoard },
\r
702 { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
\r
703 BlackRook, BlackQueen, BlackKing,
\r
704 (ChessSquare) 0, EmptySquare, ClearBoard },
\r
707 #define DROP_MENU_SIZE 6
\r
708 String dropMenuStrings[DROP_MENU_SIZE] = {
\r
709 "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
\r
711 /* must be in same order as PieceMenuStrings! */
\r
712 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
\r
713 (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
\r
714 WhiteRook, WhiteQueen
\r
722 DropMenuEnables dmEnables[] = {
\r
730 Arg shellArgs[] = {
\r
733 { XtNminWidth, 0 },
\r
734 { XtNminHeight, 0 },
\r
735 { XtNmaxWidth, 0 },
\r
736 { XtNmaxHeight, 0 }
\r
739 Arg layoutArgs[] = {
\r
740 { XtNborderWidth, 0 },
\r
741 { XtNdefaultDistance, 0 },
\r
745 { XtNborderWidth, 0 },
\r
746 { XtNresizable, (XtArgVal) True },
\r
749 Arg boardArgs[] = {
\r
750 { XtNborderWidth, 0 },
\r
755 Arg titleArgs[] = {
\r
756 { XtNjustify, (XtArgVal) XtJustifyRight },
\r
757 { XtNlabel, (XtArgVal) "..." },
\r
758 { XtNresizable, (XtArgVal) True },
\r
759 { XtNresize, (XtArgVal) False }
\r
762 Arg messageArgs[] = {
\r
763 { XtNjustify, (XtArgVal) XtJustifyLeft },
\r
764 { XtNlabel, (XtArgVal) "..." },
\r
765 { XtNresizable, (XtArgVal) True },
\r
766 { XtNresize, (XtArgVal) False }
\r
769 Arg timerArgs[] = {
\r
770 { XtNborderWidth, 0 },
\r
771 { XtNjustify, (XtArgVal) XtJustifyLeft }
\r
774 XtResource clientResources[] = {
\r
775 { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
\r
776 XtOffset(AppDataPtr, whitePieceColor), XtRString,
\r
777 WHITE_PIECE_COLOR },
\r
778 { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
\r
779 XtOffset(AppDataPtr, blackPieceColor), XtRString,
\r
780 BLACK_PIECE_COLOR },
\r
781 { "lightSquareColor", "lightSquareColor", XtRString,
\r
782 sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
\r
783 XtRString, LIGHT_SQUARE_COLOR },
\r
784 { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
\r
785 XtOffset(AppDataPtr, darkSquareColor), XtRString,
\r
786 DARK_SQUARE_COLOR },
\r
787 { "highlightSquareColor", "highlightSquareColor", XtRString,
\r
788 sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
\r
789 XtRString, HIGHLIGHT_SQUARE_COLOR },
\r
790 { "premoveHighlightColor", "premoveHighlightColor", XtRString,
\r
791 sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
\r
792 XtRString, PREMOVE_HIGHLIGHT_COLOR },
\r
793 { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
\r
794 XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
\r
795 (XtPointer) MOVES_PER_SESSION },
\r
796 { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
\r
797 XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
\r
798 (XtPointer) TIME_INCREMENT },
\r
799 { "initString", "initString", XtRString, sizeof(String),
\r
800 XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
\r
801 { "secondInitString", "secondInitString", XtRString, sizeof(String),
\r
802 XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
\r
803 { "firstComputerString", "firstComputerString", XtRString,
\r
804 sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
\r
806 { "secondComputerString", "secondComputerString", XtRString,
\r
807 sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
\r
809 { "firstChessProgram", "firstChessProgram", XtRString,
\r
810 sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
\r
811 XtRString, FIRST_CHESS_PROGRAM },
\r
812 { "secondChessProgram", "secondChessProgram", XtRString,
\r
813 sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
\r
814 XtRString, SECOND_CHESS_PROGRAM },
\r
815 { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
\r
816 sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
\r
817 XtRImmediate, (XtPointer) False },
\r
818 { "noChessProgram", "noChessProgram", XtRBoolean,
\r
819 sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
\r
820 XtRImmediate, (XtPointer) False },
\r
821 { "firstHost", "firstHost", XtRString, sizeof(String),
\r
822 XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
\r
823 { "secondHost", "secondHost", XtRString, sizeof(String),
\r
824 XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
\r
825 { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
\r
826 XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
\r
827 { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
\r
828 XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
\r
829 { "bitmapDirectory", "bitmapDirectory", XtRString,
\r
830 sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
\r
832 { "remoteShell", "remoteShell", XtRString, sizeof(String),
\r
833 XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
\r
834 { "remoteUser", "remoteUser", XtRString, sizeof(String),
\r
835 XtOffset(AppDataPtr, remoteUser), XtRString, "" },
\r
836 { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
\r
837 XtOffset(AppDataPtr, timeDelay), XtRString,
\r
838 (XtPointer) TIME_DELAY_QUOTE },
\r
839 { "timeControl", "timeControl", XtRString, sizeof(String),
\r
840 XtOffset(AppDataPtr, timeControl), XtRString,
\r
841 (XtPointer) TIME_CONTROL },
\r
842 { "internetChessServerMode", "internetChessServerMode",
\r
843 XtRBoolean, sizeof(Boolean),
\r
844 XtOffset(AppDataPtr, icsActive), XtRImmediate,
\r
845 (XtPointer) False },
\r
846 { "internetChessServerHost", "internetChessServerHost",
\r
847 XtRString, sizeof(String),
\r
848 XtOffset(AppDataPtr, icsHost),
\r
849 XtRString, (XtPointer) ICS_HOST },
\r
850 { "internetChessServerPort", "internetChessServerPort",
\r
851 XtRString, sizeof(String),
\r
852 XtOffset(AppDataPtr, icsPort), XtRString,
\r
853 (XtPointer) ICS_PORT },
\r
854 { "internetChessServerCommPort", "internetChessServerCommPort",
\r
855 XtRString, sizeof(String),
\r
856 XtOffset(AppDataPtr, icsCommPort), XtRString,
\r
858 { "internetChessServerLogonScript", "internetChessServerLogonScript",
\r
859 XtRString, sizeof(String),
\r
860 XtOffset(AppDataPtr, icsLogon), XtRString,
\r
862 { "internetChessServerHelper", "internetChessServerHelper",
\r
863 XtRString, sizeof(String),
\r
864 XtOffset(AppDataPtr, icsHelper), XtRString, "" },
\r
865 { "internetChessServerInputBox", "internetChessServerInputBox",
\r
866 XtRBoolean, sizeof(Boolean),
\r
867 XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
\r
868 (XtPointer) False },
\r
869 { "icsAlarm", "icsAlarm",
\r
870 XtRBoolean, sizeof(Boolean),
\r
871 XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
\r
872 (XtPointer) True },
\r
873 { "icsAlarmTime", "icsAlarmTime",
\r
874 XtRInt, sizeof(int),
\r
875 XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
\r
876 (XtPointer) 5000 },
\r
877 { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
\r
878 XtOffset(AppDataPtr, useTelnet), XtRImmediate,
\r
879 (XtPointer) False },
\r
880 { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
\r
881 XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
\r
882 { "gateway", "gateway", XtRString, sizeof(String),
\r
883 XtOffset(AppDataPtr, gateway), XtRString, "" },
\r
884 { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
\r
885 XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
\r
886 { "loadGameIndex", "loadGameIndex",
\r
887 XtRInt, sizeof(int),
\r
888 XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
\r
890 { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
\r
891 XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
\r
892 { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
\r
893 sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
\r
894 XtRImmediate, (XtPointer) True },
\r
895 { "autoSaveGames", "autoSaveGames", XtRBoolean,
\r
896 sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
\r
897 XtRImmediate, (XtPointer) False },
\r
898 { "blindfold", "blindfold", XtRBoolean,
\r
899 sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
\r
900 XtRImmediate, (XtPointer) False },
\r
901 { "loadPositionFile", "loadPositionFile", XtRString,
\r
902 sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
\r
904 { "loadPositionIndex", "loadPositionIndex",
\r
905 XtRInt, sizeof(int),
\r
906 XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
\r
908 { "savePositionFile", "savePositionFile", XtRString,
\r
909 sizeof(String), XtOffset(AppDataPtr, savePositionFile),
\r
911 { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
\r
912 XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
\r
913 { "matchGames", "matchGames", XtRInt, sizeof(int),
\r
914 XtOffset(AppDataPtr, matchGames), XtRImmediate,
\r
916 { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
\r
917 XtOffset(AppDataPtr, monoMode), XtRImmediate,
\r
918 (XtPointer) False },
\r
919 { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
\r
920 XtOffset(AppDataPtr, debugMode), XtRImmediate,
\r
921 (XtPointer) False },
\r
922 { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
\r
923 XtOffset(AppDataPtr, clockMode), XtRImmediate,
\r
924 (XtPointer) True },
\r
925 { "boardSize", "boardSize", XtRString, sizeof(String),
\r
926 XtOffset(AppDataPtr, boardSize), XtRString, "" },
\r
927 { "searchTime", "searchTime", XtRString, sizeof(String),
\r
928 XtOffset(AppDataPtr, searchTime), XtRString,
\r
930 { "searchDepth", "searchDepth", XtRInt, sizeof(int),
\r
931 XtOffset(AppDataPtr, searchDepth), XtRImmediate,
\r
933 { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
\r
934 XtOffset(AppDataPtr, showCoords), XtRImmediate,
\r
935 (XtPointer) False },
\r
936 { "showJail", "showJail", XtRInt, sizeof(int),
\r
937 XtOffset(AppDataPtr, showJail), XtRImmediate,
\r
939 { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
\r
940 XtOffset(AppDataPtr, showThinking), XtRImmediate,
\r
941 (XtPointer) True },
\r
942 { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
\r
943 XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
\r
944 (XtPointer) True },
\r
945 { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
\r
946 XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
\r
947 (XtPointer) True },
\r
948 { "clockFont", "clockFont", XtRString, sizeof(String),
\r
949 XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
\r
950 { "coordFont", "coordFont", XtRString, sizeof(String),
\r
951 XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
\r
952 { "font", "font", XtRString, sizeof(String),
\r
953 XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
\r
954 { "ringBellAfterMoves", "ringBellAfterMoves",
\r
955 XtRBoolean, sizeof(Boolean),
\r
956 XtOffset(AppDataPtr, ringBellAfterMoves),
\r
957 XtRImmediate, (XtPointer) False },
\r
958 { "autoCallFlag", "autoCallFlag", XtRBoolean,
\r
959 sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
\r
960 XtRImmediate, (XtPointer) False },
\r
961 { "autoFlipView", "autoFlipView", XtRBoolean,
\r
962 sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
\r
963 XtRImmediate, (XtPointer) True },
\r
964 { "autoObserve", "autoObserve", XtRBoolean,
\r
965 sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
\r
966 XtRImmediate, (XtPointer) False },
\r
967 { "autoComment", "autoComment", XtRBoolean,
\r
968 sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
\r
969 XtRImmediate, (XtPointer) False },
\r
970 { "getMoveList", "getMoveList", XtRBoolean,
\r
971 sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
\r
972 XtRImmediate, (XtPointer) True },
\r
974 { "highlightDragging", "highlightDragging", XtRBoolean,
\r
975 sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
\r
976 XtRImmediate, (XtPointer) False },
\r
978 { "highlightLastMove", "highlightLastMove", XtRBoolean,
\r
979 sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
\r
980 XtRImmediate, (XtPointer) False },
\r
981 { "premove", "premove", XtRBoolean,
\r
982 sizeof(Boolean), XtOffset(AppDataPtr, premove),
\r
983 XtRImmediate, (XtPointer) True },
\r
984 { "testLegality", "testLegality", XtRBoolean,
\r
985 sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
\r
986 XtRImmediate, (XtPointer) True },
\r
987 { "flipView", "flipView", XtRBoolean,
\r
988 sizeof(Boolean), XtOffset(AppDataPtr, flipView),
\r
989 XtRImmediate, (XtPointer) False },
\r
990 { "cmail", "cmailGameName", XtRString, sizeof(String),
\r
991 XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
\r
992 { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
\r
993 sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
\r
994 XtRImmediate, (XtPointer) False },
\r
995 { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
\r
996 sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
\r
997 XtRImmediate, (XtPointer) False },
\r
998 { "quietPlay", "quietPlay", XtRBoolean,
\r
999 sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
\r
1000 XtRImmediate, (XtPointer) False },
\r
1001 { "titleInWindow", "titleInWindow", XtRBoolean,
\r
1002 sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
\r
1003 XtRImmediate, (XtPointer) False },
\r
1004 { "localLineEditing", "localLineEditing", XtRBoolean,
\r
1005 sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
\r
1006 XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
\r
1008 { "zippyTalk", "zippyTalk", XtRBoolean,
\r
1009 sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
\r
1010 XtRImmediate, (XtPointer) ZIPPY_TALK },
\r
1011 { "zippyPlay", "zippyPlay", XtRBoolean,
\r
1012 sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
\r
1013 XtRImmediate, (XtPointer) ZIPPY_PLAY },
\r
1014 { "zippyLines", "zippyLines", XtRString, sizeof(String),
\r
1015 XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
\r
1016 { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
\r
1017 XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
\r
1018 { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
\r
1019 XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
\r
1020 { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
\r
1021 XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
\r
1022 { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
\r
1023 XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
\r
1024 ZIPPY_WRONG_PASSWORD },
\r
1025 { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
\r
1026 XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
\r
1027 { "zippyUseI", "zippyUseI", XtRBoolean,
\r
1028 sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
\r
1029 XtRImmediate, (XtPointer) ZIPPY_USE_I },
\r
1030 { "zippyBughouse", "zippyBughouse", XtRInt,
\r
1031 sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
\r
1032 XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
\r
1033 { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
\r
1034 sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
\r
1035 XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
\r
1036 { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
\r
1037 XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
\r
1038 { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
\r
1039 XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
\r
1040 { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
\r
1041 sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
\r
1042 XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
\r
1043 { "zippyAbort", "zippyAbort", XtRBoolean,
\r
1044 sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
\r
1045 XtRImmediate, (XtPointer) ZIPPY_ABORT },
\r
1046 { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
\r
1047 XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
\r
1048 { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
\r
1049 XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
\r
1050 (XtPointer) ZIPPY_MAX_GAMES },
\r
1051 { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
\r
1052 XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
\r
1053 (XtPointer) ZIPPY_REPLAY_TIMEOUT },
\r
1055 { "flashCount", "flashCount", XtRInt, sizeof(int),
\r
1056 XtOffset(AppDataPtr, flashCount), XtRImmediate,
\r
1057 (XtPointer) FLASH_COUNT },
\r
1058 { "flashRate", "flashRate", XtRInt, sizeof(int),
\r
1059 XtOffset(AppDataPtr, flashRate), XtRImmediate,
\r
1060 (XtPointer) FLASH_RATE },
\r
1061 { "pixmapDirectory", "pixmapDirectory", XtRString,
\r
1062 sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
\r
1064 { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
\r
1065 XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
\r
1066 (XtPointer) MS_LOGIN_DELAY },
\r
1067 { "colorizeMessages", "colorizeMessages", XtRBoolean,
\r
1068 sizeof(Boolean), XtOffset(AppDataPtr, colorize),
\r
1069 XtRImmediate, (XtPointer) False },
\r
1070 { "colorShout", "colorShout", XtRString,
\r
1071 sizeof(String), XtOffset(AppDataPtr, colorShout),
\r
1072 XtRString, COLOR_SHOUT },
\r
1073 { "colorSShout", "colorSShout", XtRString,
\r
1074 sizeof(String), XtOffset(AppDataPtr, colorSShout),
\r
1075 XtRString, COLOR_SSHOUT },
\r
1076 { "colorChannel1", "colorChannel1", XtRString,
\r
1077 sizeof(String), XtOffset(AppDataPtr, colorChannel1),
\r
1078 XtRString, COLOR_CHANNEL1 },
\r
1079 { "colorChannel", "colorChannel", XtRString,
\r
1080 sizeof(String), XtOffset(AppDataPtr, colorChannel),
\r
1081 XtRString, COLOR_CHANNEL },
\r
1082 { "colorKibitz", "colorKibitz", XtRString,
\r
1083 sizeof(String), XtOffset(AppDataPtr, colorKibitz),
\r
1084 XtRString, COLOR_KIBITZ },
\r
1085 { "colorTell", "colorTell", XtRString,
\r
1086 sizeof(String), XtOffset(AppDataPtr, colorTell),
\r
1087 XtRString, COLOR_TELL },
\r
1088 { "colorChallenge", "colorChallenge", XtRString,
\r
1089 sizeof(String), XtOffset(AppDataPtr, colorChallenge),
\r
1090 XtRString, COLOR_CHALLENGE },
\r
1091 { "colorRequest", "colorRequest", XtRString,
\r
1092 sizeof(String), XtOffset(AppDataPtr, colorRequest),
\r
1093 XtRString, COLOR_REQUEST },
\r
1094 { "colorSeek", "colorSeek", XtRString,
\r
1095 sizeof(String), XtOffset(AppDataPtr, colorSeek),
\r
1096 XtRString, COLOR_SEEK },
\r
1097 { "colorNormal", "colorNormal", XtRString,
\r
1098 sizeof(String), XtOffset(AppDataPtr, colorNormal),
\r
1099 XtRString, COLOR_NORMAL },
\r
1100 { "soundProgram", "soundProgram", XtRString,
\r
1101 sizeof(String), XtOffset(AppDataPtr, soundProgram),
\r
1102 XtRString, "play" },
\r
1103 { "soundShout", "soundShout", XtRString,
\r
1104 sizeof(String), XtOffset(AppDataPtr, soundShout),
\r
1106 { "soundSShout", "soundSShout", XtRString,
\r
1107 sizeof(String), XtOffset(AppDataPtr, soundSShout),
\r
1109 { "soundChannel1", "soundChannel1", XtRString,
\r
1110 sizeof(String), XtOffset(AppDataPtr, soundChannel1),
\r
1112 { "soundChannel", "soundChannel", XtRString,
\r
1113 sizeof(String), XtOffset(AppDataPtr, soundChannel),
\r
1115 { "soundKibitz", "soundKibitz", XtRString,
\r
1116 sizeof(String), XtOffset(AppDataPtr, soundKibitz),
\r
1118 { "soundTell", "soundTell", XtRString,
\r
1119 sizeof(String), XtOffset(AppDataPtr, soundTell),
\r
1121 { "soundChallenge", "soundChallenge", XtRString,
\r
1122 sizeof(String), XtOffset(AppDataPtr, soundChallenge),
\r
1124 { "soundRequest", "soundRequest", XtRString,
\r
1125 sizeof(String), XtOffset(AppDataPtr, soundRequest),
\r
1127 { "soundSeek", "soundSeek", XtRString,
\r
1128 sizeof(String), XtOffset(AppDataPtr, soundSeek),
\r
1130 { "soundMove", "soundMove", XtRString,
\r
1131 sizeof(String), XtOffset(AppDataPtr, soundMove),
\r
1133 { "soundIcsWin", "soundIcsWin", XtRString,
\r
1134 sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
\r
1136 { "soundIcsLoss", "soundIcsLoss", XtRString,
\r
1137 sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
\r
1139 { "soundIcsDraw", "soundIcsDraw", XtRString,
\r
1140 sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
\r
1142 { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
\r
1143 sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
\r
1145 { "soundIcsAlarm", "soundIcsAlarm", XtRString,
\r
1146 sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
\r
1148 { "reuseFirst", "reuseFirst", XtRBoolean,
\r
1149 sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
\r
1150 XtRImmediate, (XtPointer) True },
\r
1151 { "reuseSecond", "reuseSecond", XtRBoolean,
\r
1152 sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
\r
1153 XtRImmediate, (XtPointer) True },
\r
1154 { "animateDragging", "animateDragging", XtRBoolean,
\r
1155 sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
\r
1156 XtRImmediate, (XtPointer) True },
\r
1157 { "animateMoving", "animateMoving", XtRBoolean,
\r
1158 sizeof(Boolean), XtOffset(AppDataPtr, animate),
\r
1159 XtRImmediate, (XtPointer) True },
\r
1160 { "animateSpeed", "animateSpeed", XtRInt,
\r
1161 sizeof(int), XtOffset(AppDataPtr, animSpeed),
\r
1162 XtRImmediate, (XtPointer)10 },
\r
1163 { "popupExitMessage", "popupExitMessage", XtRBoolean,
\r
1164 sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
\r
1165 XtRImmediate, (XtPointer) True },
\r
1166 { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
\r
1167 sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
\r
1168 XtRImmediate, (XtPointer) False },
\r
1169 { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
\r
1170 sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
\r
1171 XtRImmediate, (XtPointer)4 },
\r
1172 { "initialMode", "initialMode", XtRString,
\r
1173 sizeof(String), XtOffset(AppDataPtr, initialMode),
\r
1174 XtRImmediate, (XtPointer) "" },
\r
1175 { "variant", "variant", XtRString,
\r
1176 sizeof(String), XtOffset(AppDataPtr, variant),
\r
1177 XtRImmediate, (XtPointer) "normal" },
\r
1178 { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
\r
1179 sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
\r
1180 XtRImmediate, (XtPointer)PROTOVER },
\r
1181 { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
\r
1182 sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
\r
1183 XtRImmediate, (XtPointer)PROTOVER },
\r
1184 { "showButtonBar", "showButtonBar", XtRBoolean,
\r
1185 sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
\r
1186 XtRImmediate, (XtPointer) True },
\r
1187 {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean, /* [DM] icsEngineAnalyze */
\r
1188 sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
\r
1189 XtRImmediate, (XtPointer) False },
\r
1190 { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
\r
1191 sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
\r
1192 XtRImmediate, (XtPointer) False },
\r
1193 { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
\r
1194 sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
\r
1195 XtRImmediate, (XtPointer) False },
\r
1196 { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
\r
1197 sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
\r
1198 XtRImmediate, (XtPointer) False },
\r
1199 { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
\r
1200 sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
\r
1201 XtRImmediate, (XtPointer) True },
\r
1202 { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
\r
1203 sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
\r
1204 XtRImmediate, (XtPointer) 0},
\r
1205 { "pgnEventHeader", "pgnEventHeader", XtRString,
\r
1206 sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
\r
1207 XtRImmediate, (XtPointer) "Computer Chess Game" },
\r
1208 { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
\r
1209 sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
\r
1210 XtRImmediate, (XtPointer) -1},
\r
1212 // [HGM] 4.3.xx options
\r
1213 { "boardWidth", "boardWidth", XtRInt,
\r
1214 sizeof(int), XtOffset(AppDataPtr, NrFiles),
\r
1215 XtRImmediate, (XtPointer) -1},
\r
1216 { "boardHeight", "boardHeight", XtRInt,
\r
1217 sizeof(int), XtOffset(AppDataPtr, NrRanks),
\r
1218 XtRImmediate, (XtPointer) -1},
\r
1219 { "matchPause", "matchPause", XtRInt,
\r
1220 sizeof(int), XtOffset(AppDataPtr, matchPause),
\r
1221 XtRImmediate, (XtPointer) 10000},
\r
1222 { "holdingsSize", "holdingsSize", XtRInt,
\r
1223 sizeof(int), XtOffset(AppDataPtr, holdingsSize),
\r
1224 XtRImmediate, (XtPointer) -1},
\r
1225 { "flipBlack", "flipBlack", XtRBoolean,
\r
1226 sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
\r
1227 XtRImmediate, (XtPointer) False},
\r
1228 { "allWhite", "allWhite", XtRBoolean,
\r
1229 sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
\r
1230 XtRImmediate, (XtPointer) False},
\r
1231 { "pieceToCharTable", "pieceToCharTable", XtRString,
\r
1232 sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
\r
1233 XtRImmediate, (XtPointer) 0},
\r
1234 { "alphaRank", "alphaRank", XtRBoolean,
\r
1235 sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
\r
1236 XtRImmediate, (XtPointer) False},
\r
1237 { "testClaims", "testClaims", XtRBoolean,
\r
1238 sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
\r
1239 XtRImmediate, (XtPointer) True},
\r
1240 { "checkMates", "checkMates", XtRBoolean,
\r
1241 sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
\r
1242 XtRImmediate, (XtPointer) True},
\r
1243 { "materialDraws", "materialDraws", XtRBoolean,
\r
1244 sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
\r
1245 XtRImmediate, (XtPointer) True},
\r
1246 { "trivialDraws", "trivialDraws", XtRBoolean,
\r
1247 sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
\r
1248 XtRImmediate, (XtPointer) False},
\r
1249 { "ruleMoves", "ruleMoves", XtRInt,
\r
1250 sizeof(int), XtOffset(AppDataPtr, ruleMoves),
\r
1251 XtRImmediate, (XtPointer) 51},
\r
1252 { "repeatsToDraw", "repeatsToDraw", XtRInt,
\r
1253 sizeof(int), XtOffset(AppDataPtr, drawRepeats),
\r
1254 XtRImmediate, (XtPointer) 6},
\r
1255 { "engineDebugOutput", "engineDebugOutput", XtRInt,
\r
1256 sizeof(int), XtOffset(AppDataPtr, engineComments),
\r
1257 XtRImmediate, (XtPointer) 1},
\r
1258 { "userName", "userName", XtRString,
\r
1259 sizeof(int), XtOffset(AppDataPtr, userName),
\r
1260 XtRImmediate, (XtPointer) 0},
\r
1261 { "autoKibitz", "autoKibitz", XtRBoolean,
\r
1262 sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
\r
1263 XtRImmediate, (XtPointer) False},
\r
1264 { "firstTimeOdds", "firstTimeOdds", XtRInt,
\r
1265 sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
\r
1266 XtRImmediate, (XtPointer) 1},
\r
1267 { "secondTimeOdds", "secondTimeOdds", XtRInt,
\r
1268 sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
\r
1269 XtRImmediate, (XtPointer) 1},
\r
1270 { "timeOddsMode", "timeOddsMode", XtRInt,
\r
1271 sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
\r
1272 XtRImmediate, (XtPointer) 0},
\r
1273 { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
\r
1274 sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
\r
1275 XtRImmediate, (XtPointer) 1},
\r
1276 { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
\r
1277 sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
\r
1278 XtRImmediate, (XtPointer) 1},
\r
1279 { "firstNPS", "firstNPS", XtRInt,
\r
1280 sizeof(int), XtOffset(AppDataPtr, firstNPS),
\r
1281 XtRImmediate, (XtPointer) -1},
\r
1282 { "secondNPS", "secondNPS", XtRInt,
\r
1283 sizeof(int), XtOffset(AppDataPtr, secondNPS),
\r
1284 XtRImmediate, (XtPointer) -1},
\r
1285 { "serverMoves", "serverMoves", XtRString,
\r
1286 sizeof(String), XtOffset(AppDataPtr, serverMovesName),
\r
1287 XtRImmediate, (XtPointer) 0},
\r
1288 { "serverPause", "serverPause", XtRInt,
\r
1289 sizeof(int), XtOffset(AppDataPtr, serverPause),
\r
1290 XtRImmediate, (XtPointer) 0},
\r
1291 { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
\r
1292 sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
\r
1293 XtRImmediate, (XtPointer) False},
\r
1294 { "userName", "userName", XtRString,
\r
1295 sizeof(String), XtOffset(AppDataPtr, userName),
\r
1296 XtRImmediate, (XtPointer) 0},
\r
1297 { "egtFormats", "egtFormats", XtRString,
\r
1298 sizeof(String), XtOffset(AppDataPtr, egtFormats),
\r
1299 XtRImmediate, (XtPointer) 0},
\r
1300 { "rewindIndex", "rewindIndex", XtRInt,
\r
1301 sizeof(int), XtOffset(AppDataPtr, rewindIndex),
\r
1302 XtRImmediate, (XtPointer) 0},
\r
1303 { "sameColorGames", "sameColorGames", XtRInt,
\r
1304 sizeof(int), XtOffset(AppDataPtr, sameColorGames),
\r
1305 XtRImmediate, (XtPointer) 0},
\r
1306 { "smpCores", "smpCores", XtRInt,
\r
1307 sizeof(int), XtOffset(AppDataPtr, smpCores),
\r
1308 XtRImmediate, (XtPointer) 1},
\r
1309 { "niceEngines", "niceEngines", XtRInt,
\r
1310 sizeof(int), XtOffset(AppDataPtr, niceEngines),
\r
1311 XtRImmediate, (XtPointer) 0},
\r
1312 { "nameOfDebugFile", "nameOfDebugFile", XtRString,
\r
1313 sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
\r
1314 XtRImmediate, (XtPointer) "xboard.debug"},
\r
1315 { "noGUI", "noGUI", XtRBoolean,
\r
1316 sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
\r
1317 XtRImmediate, (XtPointer) 0},
\r
1318 { "firstOptions", "firstOptions", XtRString,
\r
1319 sizeof(String), XtOffset(AppDataPtr, firstOptions),
\r
1320 XtRImmediate, (XtPointer) "" },
\r
1321 { "secondOptions", "secondOptions", XtRString,
\r
1322 sizeof(String), XtOffset(AppDataPtr, secondOptions),
\r
1323 XtRImmediate, (XtPointer) "" },
\r
1325 // [HGM] Winboard_x UCI options
\r
1326 { "firstIsUCI", "firstIsUCI", XtRBoolean,
\r
1327 sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
\r
1328 XtRImmediate, (XtPointer) False},
\r
1329 { "secondIsUCI", "secondIsUCI", XtRBoolean,
\r
1330 sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
\r
1331 XtRImmediate, (XtPointer) False},
\r
1332 { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
\r
1333 sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
\r
1334 XtRImmediate, (XtPointer) True},
\r
1335 { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
\r
1336 sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
\r
1337 XtRImmediate, (XtPointer) True},
\r
1338 { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
\r
1339 sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
\r
1340 XtRImmediate, (XtPointer) False},
\r
1341 { "defaultHashSize", "defaultHashSize", XtRInt,
\r
1342 sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
\r
1343 XtRImmediate, (XtPointer) 64},
\r
1344 { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
\r
1345 sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
\r
1346 XtRImmediate, (XtPointer) 4},
\r
1347 { "polyglotDir", "polyglotDir", XtRString,
\r
1348 sizeof(String), XtOffset(AppDataPtr, polyglotDir),
\r
1349 XtRImmediate, (XtPointer) "." },
\r
1350 { "polyglotBook", "polyglotBook", XtRString,
\r
1351 sizeof(String), XtOffset(AppDataPtr, polyglotBook),
\r
1352 XtRImmediate, (XtPointer) "" },
\r
1353 { "defaultPathEGTB", "defaultPathEGTB", XtRString,
\r
1354 sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
\r
1355 XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
\r
1356 { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
\r
1357 sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
\r
1358 XtRImmediate, (XtPointer) 0},
\r
1359 { "delayAfterQuit", "delayAfterQuit", XtRInt,
\r
1360 sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
\r
1361 XtRImmediate, (XtPointer) 0},
\r
1364 XrmOptionDescRec shellOptions[] = {
\r
1365 { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
\r
1366 { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
\r
1367 { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
\r
1368 { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
\r
1369 { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
\r
1370 { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
\r
1371 { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
\r
1372 { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
\r
1373 { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
\r
1374 { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
\r
1375 { "-initString", "initString", XrmoptionSepArg, NULL },
\r
1376 { "-firstInitString", "initString", XrmoptionSepArg, NULL },
\r
1377 { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
\r
1378 { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
\r
1379 { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
\r
1380 { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
\r
1381 { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
\r
1382 { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
\r
1383 { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
\r
1384 { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
\r
1385 { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
\r
1386 { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
\r
1387 { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
\r
1388 { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
\r
1389 { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
\r
1390 { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
\r
1391 { "-fh", "firstHost", XrmoptionSepArg, NULL },
\r
1392 { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
\r
1393 { "-sh", "secondHost", XrmoptionSepArg, NULL },
\r
1394 { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
\r
1395 { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
\r
1396 { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
\r
1397 { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
\r
1398 { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
\r
1399 { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
\r
1400 { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
\r
1401 { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
\r
1402 { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
\r
1403 { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
\r
1404 { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
\r
1405 { "-td", "timeDelay", XrmoptionSepArg, NULL },
\r
1406 { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
\r
1407 { "-tc", "timeControl", XrmoptionSepArg, NULL },
\r
1408 { "-internetChessServerMode", "internetChessServerMode",
\r
1409 XrmoptionSepArg, NULL },
\r
1410 { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
\r
1411 { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
\r
1412 { "-internetChessServerHost", "internetChessServerHost",
\r
1413 XrmoptionSepArg, NULL },
\r
1414 { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
\r
1415 { "-internetChessServerPort", "internetChessServerPort",
\r
1416 XrmoptionSepArg, NULL },
\r
1417 { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
\r
1418 { "-internetChessServerCommPort", "internetChessServerCommPort",
\r
1419 XrmoptionSepArg, NULL },
\r
1420 { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
\r
1421 { "-internetChessServerLogonScript", "internetChessServerLogonScript",
\r
1422 XrmoptionSepArg, NULL },
\r
1423 { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
\r
1424 { "-internetChessServerHelper", "internetChessServerHelper",
\r
1425 XrmoptionSepArg, NULL },
\r
1426 { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
\r
1427 { "-internetChessServerInputBox", "internetChessServerInputBox",
\r
1428 XrmoptionSepArg, NULL },
\r
1429 { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
\r
1430 { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
\r
1431 { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
\r
1432 { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
\r
1433 { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
\r
1434 { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
\r
1435 { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
\r
1436 { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
\r
1437 { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
\r
1438 { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
\r
1439 { "-gateway", "gateway", XrmoptionSepArg, NULL },
\r
1440 { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
\r
1441 { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
\r
1442 { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
\r
1443 { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
\r
1444 { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
\r
1445 { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
\r
1446 { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
\r
1447 { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
\r
1448 { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
\r
1449 { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
\r
1450 { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
\r
1451 { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
\r
1452 { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
\r
1453 { "-blind", "blindfold", XrmoptionNoArg, "True" },
\r
1454 { "-xblind", "blindfold", XrmoptionNoArg, "False" },
\r
1455 { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
\r
1456 { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
\r
1457 { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
\r
1458 { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
\r
1459 { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
\r
1460 { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
\r
1461 { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
\r
1462 { "-mm", "matchMode", XrmoptionNoArg, "True" },
\r
1463 { "-xmm", "matchMode", XrmoptionNoArg, "False" },
\r
1464 { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
\r
1465 { "-mg", "matchGames", XrmoptionSepArg, NULL },
\r
1466 { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
\r
1467 { "-mono", "monoMode", XrmoptionNoArg, "True" },
\r
1468 { "-xmono", "monoMode", XrmoptionNoArg, "False" },
\r
1469 { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
\r
1470 { "-debug", "debugMode", XrmoptionNoArg, "True" },
\r
1471 { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
\r
1472 { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
\r
1473 { "-clock", "clockMode", XrmoptionNoArg, "True" },
\r
1474 { "-xclock", "clockMode", XrmoptionNoArg, "False" },
\r
1475 { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
\r
1476 { "-size", "boardSize", XrmoptionSepArg, NULL },
\r
1477 { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
\r
1478 { "-st", "searchTime", XrmoptionSepArg, NULL },
\r
1479 { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
\r
1480 { "-depth", "searchDepth", XrmoptionSepArg, NULL },
\r
1481 { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
\r
1482 { "-coords", "showCoords", XrmoptionNoArg, "True" },
\r
1483 { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
\r
1485 { "-showJail", "showJail", XrmoptionSepArg, NULL },
\r
1486 { "-jail", "showJail", XrmoptionNoArg, "1" },
\r
1487 { "-sidejail", "showJail", XrmoptionNoArg, "2" },
\r
1488 { "-xjail", "showJail", XrmoptionNoArg, "0" },
\r
1490 { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
\r
1491 { "-thinking", "showThinking", XrmoptionNoArg, "True" },
\r
1492 { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
\r
1493 { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
\r
1494 { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
\r
1495 { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
\r
1496 { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
\r
1497 { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
\r
1498 { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
\r
1499 { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
\r
1500 { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
\r
1501 { "-font", "font", XrmoptionSepArg, NULL },
\r
1502 { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
\r
1503 { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
\r
1504 { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
\r
1505 { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
\r
1506 { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
\r
1507 { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
\r
1508 { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
\r
1509 { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
\r
1510 { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
\r
1511 { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
\r
1512 { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
\r
1513 { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
\r
1514 { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
\r
1515 { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
\r
1516 { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
\r
1517 { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
\r
1518 { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
\r
1519 { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
\r
1520 { "-moves", "getMoveList", XrmoptionNoArg, "True" },
\r
1521 { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
\r
1523 { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
\r
1524 { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
\r
1525 { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
\r
1527 { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
\r
1528 { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
\r
1529 { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
\r
1530 { "-premove", "premove", XrmoptionSepArg, NULL },
\r
1531 { "-pre", "premove", XrmoptionNoArg, "True" },
\r
1532 { "-xpre", "premove", XrmoptionNoArg, "False" },
\r
1533 { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
\r
1534 { "-legal", "testLegality", XrmoptionNoArg, "True" },
\r
1535 { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
\r
1536 { "-flipView", "flipView", XrmoptionSepArg, NULL },
\r
1537 { "-flip", "flipView", XrmoptionNoArg, "True" },
\r
1538 { "-xflip", "flipView", XrmoptionNoArg, "False" },
\r
1539 { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
\r
1540 { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
\r
1541 XrmoptionSepArg, NULL },
\r
1542 { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
\r
1543 { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
\r
1544 { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
\r
1545 { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
\r
1546 { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
\r
1547 { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
\r
1548 { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
\r
1549 { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
\r
1550 { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
\r
1551 { "-title", "titleInWindow", XrmoptionNoArg, "True" },
\r
1552 { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
\r
1554 { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
\r
1555 { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
\r
1556 { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
\r
1557 { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
\r
1558 { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
\r
1559 { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
\r
1560 { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
\r
1561 { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
\r
1562 { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
\r
1563 { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
\r
1564 { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
\r
1565 { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
\r
1566 { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
\r
1567 { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
\r
1568 { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
\r
1569 { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
\r
1570 { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
\r
1571 { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
\r
1572 { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
\r
1573 { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
\r
1574 { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
\r
1575 { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
\r
1576 { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
\r
1577 { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
\r
1578 { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
\r
1579 { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
\r
1580 { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
\r
1581 { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
\r
1582 { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
\r
1583 { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
\r
1585 { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
\r
1586 { "-flash", "flashCount", XrmoptionNoArg, "3" },
\r
1587 { "-xflash", "flashCount", XrmoptionNoArg, "0" },
\r
1588 { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
\r
1589 { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
\r
1590 { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
\r
1591 { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
\r
1592 { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
\r
1593 { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
\r
1594 { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
\r
1595 { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
\r
1596 { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
\r
1597 { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
\r
1598 { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
\r
1599 { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
\r
1600 { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
\r
1601 { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
\r
1602 { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
\r
1603 { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
\r
1604 { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
\r
1605 { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
\r
1606 { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
\r
1607 { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
\r
1608 { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
\r
1609 { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
\r
1610 { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
\r
1611 { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
\r
1612 { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
\r
1613 { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
\r
1614 { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
\r
1615 { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
\r
1616 { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
\r
1617 { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
\r
1618 { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
\r
1619 { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
\r
1620 { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
\r
1621 { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
\r
1622 { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
\r
1623 { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
\r
1624 { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
\r
1625 { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
\r
1626 { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
\r
1627 { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
\r
1628 { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
\r
1629 { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
\r
1630 { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
\r
1631 { "-animate", "animateMoving", XrmoptionNoArg, "True" },
\r
1632 { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
\r
1633 { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
\r
1634 { "-drag", "animateDragging", XrmoptionNoArg, "True" },
\r
1635 { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
\r
1636 { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
\r
1637 { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
\r
1638 { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
\r
1639 { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
\r
1640 { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
\r
1641 { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
\r
1642 { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
\r
1643 { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
\r
1644 { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
\r
1645 { "-mode", "initialMode", XrmoptionSepArg, NULL },
\r
1646 { "-variant", "variant", XrmoptionSepArg, NULL },
\r
1647 { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
\r
1648 { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
\r
1649 { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
\r
1650 { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
\r
1651 { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
\r
1652 /* [AS,HR] New features */
\r
1653 { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
\r
1654 { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
\r
1655 { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
\r
1656 { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
\r
1657 { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
\r
1658 { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
\r
1659 { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
\r
1660 { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
\r
1661 { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
\r
1662 { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
\r
1663 { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
\r
1664 { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
\r
1665 { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1666 { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1667 { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1668 { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
\r
1669 { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
\r
1670 { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
\r
1671 { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
\r
1672 { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
\r
1673 { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
\r
1674 { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
\r
1675 { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
\r
1676 // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
\r
1678 /* [HGM,HR] User-selectable board size */
\r
1679 { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
\r
1680 { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
\r
1681 { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
\r
1683 /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
\r
1684 { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
\r
1685 { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL }, // requires front-end changes to work
\r
1686 { "-allWhite", "allWhite", XrmoptionSepArg, NULL }, // requires front-end changes to work
\r
1687 { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
\r
1688 { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
\r
1689 { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
\r
1690 { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
\r
1691 { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
\r
1692 { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
\r
1693 { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
\r
1694 { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
\r
1695 { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
\r
1696 { "-userName", "userName", XrmoptionSepArg, NULL },
\r
1697 { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
\r
1698 { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
\r
1699 { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
\r
1700 { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
\r
1701 { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
\r
1702 { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
\r
1703 { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
\r
1704 { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
\r
1705 { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
\r
1706 { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
\r
1707 { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
\r
1708 { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
\r
1709 { "-userName", "userName", XrmoptionSepArg, NULL },
\r
1710 { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
\r
1711 { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
\r
1712 { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
\r
1713 { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
\r
1714 { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
\r
1715 { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
\r
1716 { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
\r
1717 { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
\r
1718 { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
\r
1719 { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
\r
1723 XtActionsRec boardActions[] = {
\r
1724 { "DrawPosition", DrawPositionProc },
\r
1725 { "HandleUserMove", HandleUserMove },
\r
1726 { "AnimateUserMove", AnimateUserMove },
\r
1727 { "FileNameAction", FileNameAction },
\r
1728 { "AskQuestionProc", AskQuestionProc },
\r
1729 { "AskQuestionReplyAction", AskQuestionReplyAction },
\r
1730 { "PieceMenuPopup", PieceMenuPopup },
\r
1731 { "WhiteClock", WhiteClock },
\r
1732 { "BlackClock", BlackClock },
\r
1733 { "Iconify", Iconify },
\r
1734 { "ResetProc", ResetProc },
\r
1735 { "LoadGameProc", LoadGameProc },
\r
1736 { "LoadNextGameProc", LoadNextGameProc },
\r
1737 { "LoadPrevGameProc", LoadPrevGameProc },
\r
1738 { "LoadSelectedProc", LoadSelectedProc },
\r
1739 { "ReloadGameProc", ReloadGameProc },
\r
1740 { "LoadPositionProc", LoadPositionProc },
\r
1741 { "LoadNextPositionProc", LoadNextPositionProc },
\r
1742 { "LoadPrevPositionProc", LoadPrevPositionProc },
\r
1743 { "ReloadPositionProc", ReloadPositionProc },
\r
1744 { "CopyPositionProc", CopyPositionProc },
\r
1745 { "PastePositionProc", PastePositionProc },
\r
1746 { "CopyGameProc", CopyGameProc },
\r
1747 { "PasteGameProc", PasteGameProc },
\r
1748 { "SaveGameProc", SaveGameProc },
\r
1749 { "SavePositionProc", SavePositionProc },
\r
1750 { "MailMoveProc", MailMoveProc },
\r
1751 { "ReloadCmailMsgProc", ReloadCmailMsgProc },
\r
1752 { "QuitProc", QuitProc },
\r
1753 { "MachineWhiteProc", MachineWhiteProc },
\r
1754 { "MachineBlackProc", MachineBlackProc },
\r
1755 { "AnalysisModeProc", AnalyzeModeProc },
\r
1756 { "AnalyzeFileProc", AnalyzeFileProc },
\r
1757 { "TwoMachinesProc", TwoMachinesProc },
\r
1758 { "IcsClientProc", IcsClientProc },
\r
1759 { "EditGameProc", EditGameProc },
\r
1760 { "EditPositionProc", EditPositionProc },
\r
1761 { "TrainingProc", EditPositionProc },
\r
1762 { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
\r
1763 { "ShowGameListProc", ShowGameListProc },
\r
1764 { "ShowMoveListProc", HistoryShowProc},
\r
1765 { "EditTagsProc", EditCommentProc },
\r
1766 { "EditCommentProc", EditCommentProc },
\r
1767 { "IcsAlarmProc", IcsAlarmProc },
\r
1768 { "IcsInputBoxProc", IcsInputBoxProc },
\r
1769 { "PauseProc", PauseProc },
\r
1770 { "AcceptProc", AcceptProc },
\r
1771 { "DeclineProc", DeclineProc },
\r
1772 { "RematchProc", RematchProc },
\r
1773 { "CallFlagProc", CallFlagProc },
\r
1774 { "DrawProc", DrawProc },
\r
1775 { "AdjournProc", AdjournProc },
\r
1776 { "AbortProc", AbortProc },
\r
1777 { "ResignProc", ResignProc },
\r
1778 { "EnterKeyProc", EnterKeyProc },
\r
1779 { "StopObservingProc", StopObservingProc },
\r
1780 { "StopExaminingProc", StopExaminingProc },
\r
1781 { "BackwardProc", BackwardProc },
\r
1782 { "ForwardProc", ForwardProc },
\r
1783 { "ToStartProc", ToStartProc },
\r
1784 { "ToEndProc", ToEndProc },
\r
1785 { "RevertProc", RevertProc },
\r
1786 { "TruncateGameProc", TruncateGameProc },
\r
1787 { "MoveNowProc", MoveNowProc },
\r
1788 { "RetractMoveProc", RetractMoveProc },
\r
1789 { "AlwaysQueenProc", AlwaysQueenProc },
\r
1790 { "AnimateDraggingProc", AnimateDraggingProc },
\r
1791 { "AnimateMovingProc", AnimateMovingProc },
\r
1792 { "AutoflagProc", AutoflagProc },
\r
1793 { "AutoflipProc", AutoflipProc },
\r
1794 { "AutobsProc", AutobsProc },
\r
1795 { "AutoraiseProc", AutoraiseProc },
\r
1796 { "AutosaveProc", AutosaveProc },
\r
1797 { "BlindfoldProc", BlindfoldProc },
\r
1798 { "FlashMovesProc", FlashMovesProc },
\r
1799 { "FlipViewProc", FlipViewProc },
\r
1800 { "GetMoveListProc", GetMoveListProc },
\r
1802 { "HighlightDraggingProc", HighlightDraggingProc },
\r
1804 { "HighlightLastMoveProc", HighlightLastMoveProc },
\r
1805 { "IcsAlarmProc", IcsAlarmProc },
\r
1806 { "MoveSoundProc", MoveSoundProc },
\r
1807 { "OldSaveStyleProc", OldSaveStyleProc },
\r
1808 { "PeriodicUpdatesProc", PeriodicUpdatesProc },
\r
1809 { "PonderNextMoveProc", PonderNextMoveProc },
\r
1810 { "PopupExitMessageProc", PopupExitMessageProc },
\r
1811 { "PopupMoveErrorsProc", PopupMoveErrorsProc },
\r
1812 { "PremoveProc", PremoveProc },
\r
1813 { "QuietPlayProc", QuietPlayProc },
\r
1814 { "ShowCoordsProc", ShowCoordsProc },
\r
1815 { "ShowThinkingProc", ShowThinkingProc },
\r
1816 { "HideThinkingProc", HideThinkingProc },
\r
1817 { "TestLegalityProc", TestLegalityProc },
\r
1818 { "InfoProc", InfoProc },
\r
1819 { "ManProc", ManProc },
\r
1820 { "HintProc", HintProc },
\r
1821 { "BookProc", BookProc },
\r
1822 { "AboutGameProc", AboutGameProc },
\r
1823 { "AboutProc", AboutProc },
\r
1824 { "DebugProc", DebugProc },
\r
1825 { "NothingProc", NothingProc },
\r
1826 { "CommentPopDown", (XtActionProc) CommentPopDown },
\r
1827 { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
\r
1828 { "TagsPopDown", (XtActionProc) TagsPopDown },
\r
1829 { "ErrorPopDown", (XtActionProc) ErrorPopDown },
\r
1830 { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
\r
1831 { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
\r
1832 { "FileNamePopDown", (XtActionProc) FileNamePopDown },
\r
1833 { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
\r
1834 { "GameListPopDown", (XtActionProc) GameListPopDown },
\r
1835 { "PromotionPopDown", (XtActionProc) PromotionPopDown },
\r
1836 { "HistoryPopDown", (XtActionProc) HistoryPopDown },
\r
1837 { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
\r
1838 { "ShufflePopDown", (XtActionProc) ShufflePopDown },
\r
1839 { "EnginePopDown", (XtActionProc) EnginePopDown },
\r
1840 { "UciPopDown", (XtActionProc) UciPopDown },
\r
1841 { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
\r
1842 { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
\r
1843 { "SettingsPopDown", (XtActionProc) SettingsPopDown },
\r
1846 char globalTranslations[] =
\r
1847 ":<Key>R: ResignProc() \n \
\r
1848 :<Key>r: ResetProc() \n \
\r
1849 :<Key>g: LoadGameProc() \n \
\r
1850 :<Key>N: LoadNextGameProc() \n \
\r
1851 :<Key>P: LoadPrevGameProc() \n \
\r
1852 :<Key>Q: QuitProc() \n \
\r
1853 :<Key>F: ToEndProc() \n \
\r
1854 :<Key>f: ForwardProc() \n \
\r
1855 :<Key>B: ToStartProc() \n \
\r
1856 :<Key>b: BackwardProc() \n \
\r
1857 :<Key>p: PauseProc() \n \
\r
1858 :<Key>d: DrawProc() \n \
\r
1859 :<Key>t: CallFlagProc() \n \
\r
1860 :<Key>i: Iconify() \n \
\r
1861 :<Key>c: Iconify() \n \
\r
1862 :<Key>v: FlipViewProc() \n \
\r
1863 <KeyDown>Control_L: BackwardProc() \n \
\r
1864 <KeyUp>Control_L: ForwardProc() \n \
\r
1865 <KeyDown>Control_R: BackwardProc() \n \
\r
1866 <KeyUp>Control_R: ForwardProc() \n \
\r
1867 Shift<Key>1: AskQuestionProc(\"Direct command\",\
\r
1868 \"Send to chess program:\",,1) \n \
\r
1869 Shift<Key>2: AskQuestionProc(\"Direct command\",\
\r
1870 \"Send to second chess program:\",,2) \n";
\r
1872 char boardTranslations[] =
\r
1873 "<Btn1Down>: HandleUserMove() \n \
\r
1874 <Btn1Up>: HandleUserMove() \n \
\r
1875 <Btn1Motion>: AnimateUserMove() \n \
\r
1876 Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
\r
1877 PieceMenuPopup(menuB) \n \
\r
1878 Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
\r
1879 PieceMenuPopup(menuW) \n \
\r
1880 Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
\r
1881 PieceMenuPopup(menuW) \n \
\r
1882 Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
\r
1883 PieceMenuPopup(menuB) \n";
\r
1885 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
\r
1886 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
\r
1888 char ICSInputTranslations[] =
\r
1889 "<Key>Return: EnterKeyProc() \n";
\r
1891 String xboardResources[] = {
\r
1892 "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
\r
1893 "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
\r
1894 "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
\r
1899 /* Max possible square size */
\r
1900 #define MAXSQSIZE 256
\r
1902 static int xpm_avail[MAXSQSIZE];
\r
1904 #ifdef HAVE_DIR_STRUCT
\r
1906 /* Extract piece size from filename */
\r
1908 xpm_getsize(name, len, ext)
\r
1919 if ((p=strchr(name, '.')) == NULL ||
\r
1920 StrCaseCmp(p+1, ext) != 0)
\r
1926 while (*p && isdigit(*p))
\r
1933 /* Setup xpm_avail */
\r
1935 xpm_getavail(dirname, ext)
\r
1940 struct dirent *ent;
\r
1943 for (i=0; i<MAXSQSIZE; ++i)
\r
1946 if (appData.debugMode)
\r
1947 fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
\r
1949 dir = opendir(dirname);
\r
1952 fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
\r
1953 programName, dirname);
\r
1957 while ((ent=readdir(dir)) != NULL) {
\r
1958 i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
\r
1959 if (i > 0 && i < MAXSQSIZE)
\r
1969 xpm_print_avail(fp, ext)
\r
1975 fprintf(fp, _("Available `%s' sizes:\n"), ext);
\r
1976 for (i=1; i<MAXSQSIZE; ++i) {
\r
1978 printf("%d\n", i);
\r
1982 /* Return XPM piecesize closest to size */
\r
1984 xpm_closest_to(dirname, size, ext)
\r
1990 int sm_diff = MAXSQSIZE;
\r
1994 xpm_getavail(dirname, ext);
\r
1996 if (appData.debugMode)
\r
1997 xpm_print_avail(stderr, ext);
\r
1999 for (i=1; i<MAXSQSIZE; ++i) {
\r
2000 if (xpm_avail[i]) {
\r
2002 diff = (diff<0) ? -diff : diff;
\r
2003 if (diff < sm_diff) {
\r
2011 fprintf(stderr, _("Error: No `%s' files!\n"), ext);
\r
2017 #else /* !HAVE_DIR_STRUCT */
\r
2018 /* If we are on a system without a DIR struct, we can't
\r
2019 read the directory, so we can't collect a list of
\r
2020 filenames, etc., so we can't do any size-fitting. */
\r
2022 xpm_closest_to(dirname, size, ext)
\r
2027 fprintf(stderr, _("\
\r
2028 Warning: No DIR structure found on this system --\n\
\r
2029 Unable to autosize for XPM/XIM pieces.\n\
\r
2030 Please report this error to frankm@hiwaay.net.\n\
\r
2031 Include system type & operating system in message.\n"));
\r
2034 #endif /* HAVE_DIR_STRUCT */
\r
2036 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
\r
2037 "magenta", "cyan", "white" };
\r
2041 TextColors textColors[(int)NColorClasses];
\r
2043 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
\r
2045 parse_color(str, which)
\r
2049 char *p, buf[100], *d;
\r
2052 if (strlen(str) > 99) /* watch bounds on buf */
\r
2057 for (i=0; i<which; ++i) {
\r
2058 p = strchr(p, ',');
\r
2064 /* Could be looking at something like:
\r
2066 .. in which case we want to stop on a comma also */
\r
2067 while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
\r
2071 return -1; /* Use default for empty field */
\r
2074 if (which == 2 || isdigit(*p))
\r
2077 while (*p && isalpha(*p))
\r
2082 for (i=0; i<8; ++i) {
\r
2083 if (!StrCaseCmp(buf, cnames[i]))
\r
2084 return which? (i+40) : (i+30);
\r
2086 if (!StrCaseCmp(buf, "default")) return -1;
\r
2088 fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
\r
2093 parse_cpair(cc, str)
\r
2097 if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
\r
2098 fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
\r
2099 programName, str);
\r
2103 /* bg and attr are optional */
\r
2104 textColors[(int)cc].bg = parse_color(str, 1);
\r
2105 if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
\r
2106 textColors[(int)cc].attr = 0;
\r
2112 /* Arrange to catch delete-window events */
\r
2113 Atom wm_delete_window;
\r
2115 CatchDeleteWindow(Widget w, String procname)
\r
2117 char buf[MSG_SIZ];
\r
2118 XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
\r
2119 sprintf(buf, "<Message>WM_PROTOCOLS: %s() \n", procname);
\r
2120 XtAugmentTranslations(w, XtParseTranslationTable(buf));
\r
2127 XtSetArg(args[0], XtNiconic, False);
\r
2128 XtSetValues(shellWidget, args, 1);
\r
2130 XtPopup(shellWidget, XtGrabNone); /* Raise if lowered */
\r
2134 // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
\r
2136 #define BoardSize int
\r
2137 void InitDrawingSizes(BoardSize boardSize, int flags)
\r
2138 { // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
\r
2139 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
\r
2141 XtGeometryResult gres;
\r
2144 if(!formWidget) return;
\r
2147 * Enable shell resizing.
\r
2149 shellArgs[0].value = (XtArgVal) &w;
\r
2150 shellArgs[1].value = (XtArgVal) &h;
\r
2151 XtGetValues(shellWidget, shellArgs, 2);
\r
2153 shellArgs[4].value = 2*w; shellArgs[2].value = 10;
\r
2154 shellArgs[5].value = 2*h; shellArgs[3].value = 10;
\r
2155 XtSetValues(shellWidget, &shellArgs[2], 4);
\r
2157 XtSetArg(args[0], XtNdefaultDistance, &sep);
\r
2158 XtGetValues(formWidget, args, 1);
\r
2160 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
2161 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
2164 XtSetArg(args[0], XtNwidth, boardWidth);
\r
2165 XtSetArg(args[1], XtNheight, boardHeight);
\r
2166 XtSetValues(boardWidget, args, 2);
\r
2168 timerWidth = (boardWidth - sep) / 2;
\r
2169 XtSetArg(args[0], XtNwidth, timerWidth);
\r
2170 XtSetValues(whiteTimerWidget, args, 1);
\r
2171 XtSetValues(blackTimerWidget, args, 1);
\r
2173 XawFormDoLayout(formWidget, False);
\r
2175 if (appData.titleInWindow) {
\r
2177 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2178 XtSetArg(args[i], XtNheight, &h); i++;
\r
2179 XtGetValues(titleWidget, args, i);
\r
2180 if (smallLayout) {
\r
2181 w = boardWidth - 2*bor;
\r
2183 XtSetArg(args[0], XtNwidth, &w);
\r
2184 XtGetValues(menuBarWidget, args, 1);
\r
2185 w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
\r
2188 gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
\r
2189 if (gres != XtGeometryYes && appData.debugMode) {
\r
2191 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
\r
2192 programName, gres, w, h, wr, hr);
\r
2196 XawFormDoLayout(formWidget, True);
\r
2199 * Inhibit shell resizing.
\r
2201 shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
\r
2202 shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
\r
2203 shellArgs[4].value = shellArgs[2].value = w;
\r
2204 shellArgs[5].value = shellArgs[3].value = h;
\r
2205 XtSetValues(shellWidget, &shellArgs[0], 6);
\r
2214 int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
\r
2215 XSetWindowAttributes window_attributes;
\r
2217 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
\r
2218 XrmValue vFrom, vTo;
\r
2219 XtGeometryResult gres;
\r
2222 int forceMono = False;
\r
2223 #define INDIRECTION
\r
2224 #ifdef INDIRECTION
\r
2225 // [HGM] before anything else, expand any indirection files amongst options
\r
2226 char *argvCopy[1000]; // 1000 seems enough
\r
2227 char newArgs[10000]; // holds actual characters
\r
2230 srandom(time(0)); // [HGM] book: make random truly random
\r
2233 for(i=0; i<argc; i++) {
\r
2234 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
\r
2235 //fprintf(stderr, "arg %s\n", argv[i]);
\r
2236 if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
\r
2238 FILE *f = fopen(argv[i]+1, "rb");
\r
2239 if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
\r
2240 argvCopy[j++] = newArgs + k; // get ready for first argument from file
\r
2241 while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
\r
2243 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
\r
2244 newArgs[k++] = 0; // terminate current arg
\r
2245 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
\r
2246 argvCopy[j++] = newArgs + k; // get ready for next
\r
2248 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
\r
2257 argvCopy[j] = NULL;
\r
2261 if(appData.debugMode,1) { // OK, appData is not initialized here yet...
\r
2262 for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
\r
2268 setbuf(stdout, NULL);
\r
2269 setbuf(stderr, NULL);
\r
2272 programName = strrchr(argv[0], '/');
\r
2273 if (programName == NULL)
\r
2274 programName = argv[0];
\r
2279 XtSetLanguageProc(NULL, NULL, NULL);
\r
2280 bindtextdomain(PRODUCT, LOCALEDIR);
\r
2281 textdomain(PRODUCT);
\r
2285 XtAppInitialize(&appContext, "XBoard", shellOptions,
\r
2286 XtNumber(shellOptions),
\r
2287 &argc, argv, xboardResources, NULL, 0);
\r
2289 fprintf(stderr, _("%s: unrecognized argument %s\n"),
\r
2290 programName, argv[1]);
\r
2294 if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
\r
2297 if (chdir(chessDir) != 0) {
\r
2298 fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
\r
2304 p = getenv("HOME");
\r
2305 if (p == NULL) p = "/tmp";
\r
2306 i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
\r
2307 gameCopyFilename = (char*) malloc(i);
\r
2308 gamePasteFilename = (char*) malloc(i);
\r
2309 sprintf(gameCopyFilename, "%s/.xboard%05uc.pgn", p, getpid());
\r
2310 sprintf(gamePasteFilename, "%s/.xboard%05up.pgn", p, getpid());
\r
2312 XtGetApplicationResources(shellWidget, (XtPointer) &appData,
\r
2313 clientResources, XtNumber(clientResources),
\r
2316 if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
\r
2317 /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
\r
2318 if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL) {
\r
2319 printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
\r
2322 setbuf(debugFP, NULL);
\r
2325 /* [HGM,HR] make sure board size is acceptable */
\r
2326 if(appData.NrFiles > BOARD_SIZE ||
\r
2327 appData.NrRanks > BOARD_SIZE )
\r
2328 DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
\r
2331 /* This feature does not work; animation needs a rewrite */
\r
2332 appData.highlightDragging = FALSE;
\r
2336 xDisplay = XtDisplay(shellWidget);
\r
2337 xScreen = DefaultScreen(xDisplay);
\r
2338 wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
\r
2340 gameInfo.variant = StringToVariant(appData.variant);
\r
2341 InitPosition(FALSE);
\r
2344 * Determine boardSize
\r
2346 gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
\r
2349 // [HGM] as long as we have not created the possibility to change size while running, start with requested size
\r
2350 gameInfo.boardWidth = appData.NrFiles > 0 ? appData.NrFiles : 8;
\r
2351 gameInfo.boardHeight = appData.NrRanks > 0 ? appData.NrRanks : 8;
\r
2352 gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
\r
2357 InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
\r
2359 if (isdigit(appData.boardSize[0])) {
\r
2360 i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
\r
2361 &lineGap, &clockFontPxlSize, &coordFontPxlSize,
\r
2362 &fontPxlSize, &smallLayout, &tinyLayout);
\r
2364 fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
\r
2365 programName, appData.boardSize);
\r
2369 /* Find some defaults; use the nearest known size */
\r
2370 SizeDefaults *szd, *nearest;
\r
2371 int distance = 99999;
\r
2372 nearest = szd = sizeDefaults;
\r
2373 while (szd->name != NULL) {
\r
2374 if (abs(szd->squareSize - squareSize) < distance) {
\r
2376 distance = abs(szd->squareSize - squareSize);
\r
2377 if (distance == 0) break;
\r
2381 if (i < 2) lineGap = nearest->lineGap;
\r
2382 if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
\r
2383 if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
\r
2384 if (i < 5) fontPxlSize = nearest->fontPxlSize;
\r
2385 if (i < 6) smallLayout = nearest->smallLayout;
\r
2386 if (i < 7) tinyLayout = nearest->tinyLayout;
\r
2389 SizeDefaults *szd = sizeDefaults;
\r
2390 if (*appData.boardSize == NULLCHAR) {
\r
2391 while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
\r
2392 DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
\r
2395 if (szd->name == NULL) szd--;
\r
2397 while (szd->name != NULL &&
\r
2398 StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
\r
2399 if (szd->name == NULL) {
\r
2400 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
\r
2401 programName, appData.boardSize);
\r
2405 squareSize = szd->squareSize;
\r
2406 lineGap = szd->lineGap;
\r
2407 clockFontPxlSize = szd->clockFontPxlSize;
\r
2408 coordFontPxlSize = szd->coordFontPxlSize;
\r
2409 fontPxlSize = szd->fontPxlSize;
\r
2410 smallLayout = szd->smallLayout;
\r
2411 tinyLayout = szd->tinyLayout;
\r
2414 /* Now, using squareSize as a hint, find a good XPM/XIM set size */
\r
2415 if (strlen(appData.pixmapDirectory) > 0) {
\r
2416 p = ExpandPathName(appData.pixmapDirectory);
\r
2418 fprintf(stderr, _("Error expanding path name \"%s\"\n"),
\r
2419 appData.pixmapDirectory);
\r
2422 if (appData.debugMode) {
\r
2423 fprintf(stderr, _("\
\r
2424 XBoard square size (hint): %d\n\
\r
2425 %s fulldir:%s:\n"), squareSize, IMAGE_EXT, p);
\r
2427 squareSize = xpm_closest_to(p, squareSize, IMAGE_EXT);
\r
2428 if (appData.debugMode) {
\r
2429 fprintf(stderr, _("Closest %s size: %d\n"), IMAGE_EXT, squareSize);
\r
2433 /* [HR] height treated separately (hacked) */
\r
2434 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
2435 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
2436 if (appData.showJail == 1) {
\r
2437 /* Jail on top and bottom */
\r
2438 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
\r
2439 XtSetArg(boardArgs[2], XtNheight,
\r
2440 boardHeight + 2*(lineGap + squareSize));
\r
2441 } else if (appData.showJail == 2) {
\r
2442 /* Jail on sides */
\r
2443 XtSetArg(boardArgs[1], XtNwidth,
\r
2444 boardWidth + 2*(lineGap + squareSize));
\r
2445 XtSetArg(boardArgs[2], XtNheight, boardHeight);
\r
2448 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
\r
2449 XtSetArg(boardArgs[2], XtNheight, boardHeight);
\r
2453 * Determine what fonts to use.
\r
2455 appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
\r
2456 clockFontID = XLoadFont(xDisplay, appData.clockFont);
\r
2457 clockFontStruct = XQueryFont(xDisplay, clockFontID);
\r
2458 appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
\r
2459 coordFontID = XLoadFont(xDisplay, appData.coordFont);
\r
2460 coordFontStruct = XQueryFont(xDisplay, coordFontID);
\r
2461 appData.font = FindFont(appData.font, fontPxlSize);
\r
2462 countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
\r
2463 countFontStruct = XQueryFont(xDisplay, countFontID);
\r
2464 // appData.font = FindFont(appData.font, fontPxlSize);
\r
2466 xdb = XtDatabase(xDisplay);
\r
2467 XrmPutStringResource(&xdb, "*font", appData.font);
\r
2470 * Detect if there are not enough colors available and adapt.
\r
2472 if (DefaultDepth(xDisplay, xScreen) <= 2) {
\r
2473 appData.monoMode = True;
\r
2476 if (!appData.monoMode) {
\r
2477 vFrom.addr = (caddr_t) appData.lightSquareColor;
\r
2478 vFrom.size = strlen(appData.lightSquareColor);
\r
2479 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2480 if (vTo.addr == NULL) {
\r
2481 appData.monoMode = True;
\r
2484 lightSquareColor = *(Pixel *) vTo.addr;
\r
2487 if (!appData.monoMode) {
\r
2488 vFrom.addr = (caddr_t) appData.darkSquareColor;
\r
2489 vFrom.size = strlen(appData.darkSquareColor);
\r
2490 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2491 if (vTo.addr == NULL) {
\r
2492 appData.monoMode = True;
\r
2495 darkSquareColor = *(Pixel *) vTo.addr;
\r
2498 if (!appData.monoMode) {
\r
2499 vFrom.addr = (caddr_t) appData.whitePieceColor;
\r
2500 vFrom.size = strlen(appData.whitePieceColor);
\r
2501 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2502 if (vTo.addr == NULL) {
\r
2503 appData.monoMode = True;
\r
2506 whitePieceColor = *(Pixel *) vTo.addr;
\r
2509 if (!appData.monoMode) {
\r
2510 vFrom.addr = (caddr_t) appData.blackPieceColor;
\r
2511 vFrom.size = strlen(appData.blackPieceColor);
\r
2512 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2513 if (vTo.addr == NULL) {
\r
2514 appData.monoMode = True;
\r
2517 blackPieceColor = *(Pixel *) vTo.addr;
\r
2521 if (!appData.monoMode) {
\r
2522 vFrom.addr = (caddr_t) appData.highlightSquareColor;
\r
2523 vFrom.size = strlen(appData.highlightSquareColor);
\r
2524 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2525 if (vTo.addr == NULL) {
\r
2526 appData.monoMode = True;
\r
2529 highlightSquareColor = *(Pixel *) vTo.addr;
\r
2533 if (!appData.monoMode) {
\r
2534 vFrom.addr = (caddr_t) appData.premoveHighlightColor;
\r
2535 vFrom.size = strlen(appData.premoveHighlightColor);
\r
2536 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
\r
2537 if (vTo.addr == NULL) {
\r
2538 appData.monoMode = True;
\r
2541 premoveHighlightColor = *(Pixel *) vTo.addr;
\r
2546 fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
\r
2550 if (appData.monoMode && appData.debugMode) {
\r
2551 fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
\r
2552 (unsigned long) XWhitePixel(xDisplay, xScreen),
\r
2553 (unsigned long) XBlackPixel(xDisplay, xScreen));
\r
2556 if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
\r
2557 parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
\r
2558 parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||
\r
2559 parse_cpair(ColorChannel, appData.colorChannel) < 0 ||
\r
2560 parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
\r
2561 parse_cpair(ColorTell, appData.colorTell) < 0 ||
\r
2562 parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||
\r
2563 parse_cpair(ColorRequest, appData.colorRequest) < 0 ||
\r
2564 parse_cpair(ColorSeek, appData.colorSeek) < 0 ||
\r
2565 parse_cpair(ColorNormal, appData.colorNormal) < 0)
\r
2567 if (appData.colorize) {
\r
2569 _("%s: can't parse color names; disabling colorization\n"),
\r
2572 appData.colorize = FALSE;
\r
2574 textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
\r
2575 textColors[ColorNone].attr = 0;
\r
2577 XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
\r
2580 * widget hierarchy
\r
2583 layoutName = "tinyLayout";
\r
2584 } else if (smallLayout) {
\r
2585 layoutName = "smallLayout";
\r
2587 layoutName = "normalLayout";
\r
2589 /* Outer layoutWidget is there only to provide a name for use in
\r
2590 resources that depend on the layout style */
\r
2592 XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
\r
2593 layoutArgs, XtNumber(layoutArgs));
\r
2595 XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
\r
2596 formArgs, XtNumber(formArgs));
\r
2597 XtSetArg(args[0], XtNdefaultDistance, &sep);
\r
2598 XtGetValues(formWidget, args, 1);
\r
2601 widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
\r
2602 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2603 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2604 XtSetValues(menuBarWidget, args, 2);
\r
2606 widgetList[j++] = whiteTimerWidget =
\r
2607 XtCreateWidget("whiteTime", labelWidgetClass,
\r
2608 formWidget, timerArgs, XtNumber(timerArgs));
\r
2609 XtSetArg(args[0], XtNfont, clockFontStruct);
\r
2610 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2611 XtSetArg(args[2], XtNbottom, XtChainTop);
\r
2612 XtSetValues(whiteTimerWidget, args, 3);
\r
2614 widgetList[j++] = blackTimerWidget =
\r
2615 XtCreateWidget("blackTime", labelWidgetClass,
\r
2616 formWidget, timerArgs, XtNumber(timerArgs));
\r
2617 XtSetArg(args[0], XtNfont, clockFontStruct);
\r
2618 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2619 XtSetArg(args[2], XtNbottom, XtChainTop);
\r
2620 XtSetValues(blackTimerWidget, args, 3);
\r
2622 if (appData.titleInWindow) {
\r
2623 widgetList[j++] = titleWidget =
\r
2624 XtCreateWidget("title", labelWidgetClass, formWidget,
\r
2625 titleArgs, XtNumber(titleArgs));
\r
2626 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2627 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2628 XtSetValues(titleWidget, args, 2);
\r
2631 if (appData.showButtonBar) {
\r
2632 widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
\r
2633 XtSetArg(args[0], XtNleft, XtChainRight); // [HGM] glue to right window edge
\r
2634 XtSetArg(args[1], XtNright, XtChainRight); // for good run-time sizing
\r
2635 XtSetArg(args[2], XtNtop, XtChainTop);
\r
2636 XtSetArg(args[3], XtNbottom, XtChainTop);
\r
2637 XtSetValues(buttonBarWidget, args, 4);
\r
2640 widgetList[j++] = messageWidget =
\r
2641 XtCreateWidget("message", labelWidgetClass, formWidget,
\r
2642 messageArgs, XtNumber(messageArgs));
\r
2643 XtSetArg(args[0], XtNtop, XtChainTop);
\r
2644 XtSetArg(args[1], XtNbottom, XtChainTop);
\r
2645 XtSetValues(messageWidget, args, 2);
\r
2647 widgetList[j++] = boardWidget =
\r
2648 XtCreateWidget("board", widgetClass, formWidget, boardArgs,
\r
2649 XtNumber(boardArgs));
\r
2651 XtManageChildren(widgetList, j);
\r
2653 timerWidth = (boardWidth - sep) / 2;
\r
2654 XtSetArg(args[0], XtNwidth, timerWidth);
\r
2655 XtSetValues(whiteTimerWidget, args, 1);
\r
2656 XtSetValues(blackTimerWidget, args, 1);
\r
2658 XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
\r
2659 XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
\r
2660 XtGetValues(whiteTimerWidget, args, 2);
\r
2662 if (appData.showButtonBar) {
\r
2663 XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
\r
2664 XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
\r
2665 XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
\r
2669 * formWidget uses these constraints but they are stored
\r
2670 * in the children.
\r
2673 XtSetArg(args[i], XtNfromHoriz, 0); i++;
\r
2674 XtSetValues(menuBarWidget, args, i);
\r
2675 if (appData.titleInWindow) {
\r
2676 if (smallLayout) {
\r
2678 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2679 XtSetValues(whiteTimerWidget, args, i);
\r
2681 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2682 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2683 XtSetValues(blackTimerWidget, args, i);
\r
2685 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2686 XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
\r
2687 XtSetValues(titleWidget, args, i);
\r
2689 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2690 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2691 XtSetValues(messageWidget, args, i);
\r
2692 if (appData.showButtonBar) {
\r
2694 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2695 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2696 XtSetValues(buttonBarWidget, args, i);
\r
2700 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2701 XtSetValues(whiteTimerWidget, args, i);
\r
2703 XtSetArg(args[i], XtNfromVert, titleWidget); i++;
\r
2704 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2705 XtSetValues(blackTimerWidget, args, i);
\r
2707 XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
\r
2708 XtSetValues(titleWidget, args, i);
\r
2710 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2711 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2712 XtSetValues(messageWidget, args, i);
\r
2713 if (appData.showButtonBar) {
\r
2715 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2716 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2717 XtSetValues(buttonBarWidget, args, i);
\r
2722 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2723 XtSetValues(whiteTimerWidget, args, i);
\r
2725 XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
\r
2726 XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
\r
2727 XtSetValues(blackTimerWidget, args, i);
\r
2729 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2730 XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
\r
2731 XtSetValues(messageWidget, args, i);
\r
2732 if (appData.showButtonBar) {
\r
2734 XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
\r
2735 XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
\r
2736 XtSetValues(buttonBarWidget, args, i);
\r
2740 XtSetArg(args[0], XtNfromVert, messageWidget);
\r
2741 XtSetArg(args[1], XtNtop, XtChainTop);
\r
2742 XtSetArg(args[2], XtNbottom, XtChainBottom);
\r
2743 XtSetArg(args[3], XtNleft, XtChainLeft);
\r
2744 XtSetArg(args[4], XtNright, XtChainRight);
\r
2745 XtSetValues(boardWidget, args, 5);
\r
2747 XtRealizeWidget(shellWidget);
\r
2750 * Correct the width of the message and title widgets.
\r
2751 * It is not known why some systems need the extra fudge term.
\r
2752 * The value "2" is probably larger than needed.
\r
2754 XawFormDoLayout(formWidget, False);
\r
2756 #define WIDTH_FUDGE 2
\r
2758 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2759 XtSetArg(args[i], XtNheight, &h); i++;
\r
2760 XtGetValues(messageWidget, args, i);
\r
2761 if (appData.showButtonBar) {
\r
2763 XtSetArg(args[i], XtNwidth, &w); i++;
\r
2764 XtGetValues(buttonBarWidget, args, i);
\r
2765 w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
\r
2767 w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
\r
2770 gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
\r
2771 if (gres != XtGeometryYes && appData.debugMode) {
\r
2772 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
\r
2773 programName, gres, w, h, wr, hr);
\r
2776 /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
\r
2777 /* The size used for the child widget in layout lags one resize behind
\r
2778 its true size, so we resize a second time, 1 pixel smaller. Yeech! */
\r
2780 gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
\r
2781 if (gres != XtGeometryYes && appData.debugMode) {
\r
2782 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
\r
2783 programName, gres, w, h, wr, hr);
\r
2786 XtSetArg(args[0], XtNleft, XtChainLeft); // [HGM] glue ends for good run-time sizing
\r
2787 XtSetArg(args[1], XtNright, XtChainRight);
\r
2788 XtSetValues(messageWidget, args, 2);
\r
2790 if (appData.titleInWindow) {
\r
2792 XtSetArg(args[i], XtNborderWidth, &bor); i++;
\r
2793 XtSetArg(args[i], XtNheight, &h); i++;
\r
2794 XtGetValues(titleWidget, args, i);
\r
2795 if (smallLayout) {
\r
2796 w = boardWidth - 2*bor;
\r
2798 XtSetArg(args[0], XtNwidth, &w);
\r
2799 XtGetValues(menuBarWidget, args, 1);
\r
2800 w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
\r
2803 gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
\r
2804 if (gres != XtGeometryYes && appData.debugMode) {
\r
2806 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
\r
2807 programName, gres, w, h, wr, hr);
\r
2810 XawFormDoLayout(formWidget, True);
\r
2812 xBoardWindow = XtWindow(boardWidget);
\r
2814 // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
\r
2815 // not need to go into InitDrawingSizes().
\r
2819 * Create X checkmark bitmap and initialize option menu checks.
\r
2821 ReadBitmap(&xMarkPixmap, "checkmark.bm",
\r
2822 checkmark_bits, checkmark_width, checkmark_height);
\r
2823 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
2824 if (appData.alwaysPromoteToQueen) {
\r
2825 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
\r
2828 if (appData.animateDragging) {
\r
2829 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2830 "menuOptions.Animate Dragging"),
\r
2833 if (appData.animate) {
\r
2834 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
\r
2837 if (appData.autoComment) {
\r
2838 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
\r
2841 if (appData.autoCallFlag) {
\r
2842 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
\r
2845 if (appData.autoFlipView) {
\r
2846 XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"),
\r
2849 if (appData.autoObserve) {
\r
2850 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
\r
2853 if (appData.autoRaiseBoard) {
\r
2854 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2855 "menuOptions.Auto Raise Board"), args, 1);
\r
2857 if (appData.autoSaveGames) {
\r
2858 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2861 if (appData.saveGameFile[0] != NULLCHAR) {
\r
2862 /* Can't turn this off from menu */
\r
2863 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2865 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
2869 if (appData.blindfold) {
\r
2870 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2871 "menuOptions.Blindfold"), args, 1);
\r
2873 if (appData.flashCount > 0) {
\r
2874 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2875 "menuOptions.Flash Moves"),
\r
2878 if (appData.getMoveList) {
\r
2879 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
\r
2883 if (appData.highlightDragging) {
\r
2884 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2885 "menuOptions.Highlight Dragging"),
\r
2889 if (appData.highlightLastMove) {
\r
2890 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2891 "menuOptions.Highlight Last Move"),
\r
2894 if (appData.icsAlarm) {
\r
2895 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
\r
2898 if (appData.ringBellAfterMoves) {
\r
2899 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
\r
2902 if (appData.oldSaveStyle) {
\r
2903 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2904 "menuOptions.Old Save Style"), args, 1);
\r
2906 if (appData.periodicUpdates) {
\r
2907 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2908 "menuOptions.Periodic Updates"), args, 1);
\r
2910 if (appData.ponderNextMove) {
\r
2911 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2912 "menuOptions.Ponder Next Move"), args, 1);
\r
2914 if (appData.popupExitMessage) {
\r
2915 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2916 "menuOptions.Popup Exit Message"), args, 1);
\r
2918 if (appData.popupMoveErrors) {
\r
2919 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2920 "menuOptions.Popup Move Errors"), args, 1);
\r
2922 if (appData.premove) {
\r
2923 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2924 "menuOptions.Premove"), args, 1);
\r
2926 if (appData.quietPlay) {
\r
2927 XtSetValues(XtNameToWidget(menuBarWidget,
\r
2928 "menuOptions.Quiet Play"), args, 1);
\r
2930 if (appData.showCoords) {
\r
2931 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
\r
2934 if (appData.hideThinkingFromHuman) {
\r
2935 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
\r
2938 if (appData.testLegality) {
\r
2939 XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"),
\r
2946 ReadBitmap(&wIconPixmap, "icon_white.bm",
\r
2947 icon_white_bits, icon_white_width, icon_white_height);
\r
2948 ReadBitmap(&bIconPixmap, "icon_black.bm",
\r
2949 icon_black_bits, icon_black_width, icon_black_height);
\r
2950 iconPixmap = wIconPixmap;
\r
2952 XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;
\r
2953 XtSetValues(shellWidget, args, i);
\r
2956 * Create a cursor for the board widget.
\r
2958 window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
\r
2959 XChangeWindowAttributes(xDisplay, xBoardWindow,
\r
2960 CWCursor, &window_attributes);
\r
2963 * Inhibit shell resizing.
\r
2965 shellArgs[0].value = (XtArgVal) &w;
\r
2966 shellArgs[1].value = (XtArgVal) &h;
\r
2967 XtGetValues(shellWidget, shellArgs, 2);
\r
2968 shellArgs[4].value = shellArgs[2].value = w;
\r
2969 shellArgs[5].value = shellArgs[3].value = h;
\r
2970 XtSetValues(shellWidget, &shellArgs[2], 4);
\r
2971 marginW = w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board
\r
2972 marginH = h - boardHeight;
\r
2974 CatchDeleteWindow(shellWidget, "QuitProc");
\r
2979 if (appData.bitmapDirectory[0] != NULLCHAR) {
\r
2982 CreateXPMPieces();
\r
2985 CreateXIMPieces();
\r
2986 /* Create regular pieces */
\r
2987 if (!useImages) CreatePieces();
\r
2990 CreatePieceMenus();
\r
2992 if (appData.animate || appData.animateDragging)
\r
2995 XtAugmentTranslations(formWidget,
\r
2996 XtParseTranslationTable(globalTranslations));
\r
2997 XtAugmentTranslations(boardWidget,
\r
2998 XtParseTranslationTable(boardTranslations));
\r
2999 XtAugmentTranslations(whiteTimerWidget,
\r
3000 XtParseTranslationTable(whiteTranslations));
\r
3001 XtAugmentTranslations(blackTimerWidget,
\r
3002 XtParseTranslationTable(blackTranslations));
\r
3004 /* Why is the following needed on some versions of X instead
\r
3005 * of a translation? */
\r
3006 XtAddEventHandler(boardWidget, ExposureMask, False,
\r
3007 (XtEventHandler) EventProc, NULL);
\r
3012 if (errorExitStatus == -1) {
\r
3013 if (appData.icsActive) {
\r
3014 /* We now wait until we see "login:" from the ICS before
\r
3015 sending the logon script (problems with timestamp otherwise) */
\r
3016 /*ICSInitScript();*/
\r
3017 if (appData.icsInputBox) ICSInputBoxPopUp();
\r
3020 signal(SIGINT, IntSigHandler);
\r
3021 signal(SIGTERM, IntSigHandler);
\r
3022 if (*appData.cmailGameName != NULLCHAR) {
\r
3023 signal(SIGUSR1, CmailSigHandler);
\r
3026 InitPosition(TRUE);
\r
3028 XtAppMainLoop(appContext);
\r
3029 if (appData.debugMode) fclose(debugFP); // [DM] debug
\r
3034 ShutDownFrontEnd()
\r
3036 if (appData.icsActive && oldICSInteractionTitle != NULL) {
\r
3037 DisplayIcsInteractionTitle(oldICSInteractionTitle);
\r
3039 unlink(gameCopyFilename);
\r
3040 unlink(gamePasteFilename);
\r
3044 IntSigHandler(sig)
\r
3051 CmailSigHandler(sig)
\r
3057 signal(SIGUSR1, SIG_IGN); /* suspend handler */
\r
3059 /* Activate call-back function CmailSigHandlerCallBack() */
\r
3060 OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
\r
3062 signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
\r
3066 CmailSigHandlerCallBack(isr, closure, message, count, error)
\r
3067 InputSourceRef isr;
\r
3074 ReloadCmailMsgEvent(TRUE); /* Reload cmail msg */
\r
3076 /**** end signal code ****/
\r
3083 char buf[MSG_SIZ];
\r
3086 f = fopen(appData.icsLogon, "r");
\r
3088 p = getenv("HOME");
\r
3092 strcat(buf, appData.icsLogon);
\r
3093 f = fopen(buf, "r");
\r
3097 ProcessICSInitScript(f);
\r
3104 EditCommentPopDown();
\r
3115 SetMenuEnables(enab)
\r
3119 if (!menuBarWidget) return;
\r
3120 while (enab->name != NULL) {
\r
3121 w = XtNameToWidget(menuBarWidget, enab->name);
\r
3123 DisplayError(enab->name, 0);
\r
3125 XtSetSensitive(w, enab->value);
\r
3131 Enables icsEnables[] = {
\r
3132 { "menuFile.Mail Move", False },
\r
3133 { "menuFile.Reload CMail Message", False },
\r
3134 { "menuMode.Machine Black", False },
\r
3135 { "menuMode.Machine White", False },
\r
3136 { "menuMode.Analysis Mode", False },
\r
3137 { "menuMode.Analyze File", False },
\r
3138 { "menuMode.Two Machines", False },
\r
3140 { "menuHelp.Hint", False },
\r
3141 { "menuHelp.Book", False },
\r
3142 { "menuStep.Move Now", False },
\r
3143 { "menuOptions.Periodic Updates", False },
\r
3144 { "menuOptions.Hide Thinking", False },
\r
3145 { "menuOptions.Ponder Next Move", False },
\r
3150 Enables ncpEnables[] = {
\r
3151 { "menuFile.Mail Move", False },
\r
3152 { "menuFile.Reload CMail Message", False },
\r
3153 { "menuMode.Machine White", False },
\r
3154 { "menuMode.Machine Black", False },
\r
3155 { "menuMode.Analysis Mode", False },
\r
3156 { "menuMode.Analyze File", False },
\r
3157 { "menuMode.Two Machines", False },
\r
3158 { "menuMode.ICS Client", False },
\r
3159 { "menuMode.ICS Input Box", False },
\r
3160 { "Action", False },
\r
3161 { "menuStep.Revert", False },
\r
3162 { "menuStep.Move Now", False },
\r
3163 { "menuStep.Retract Move", False },
\r
3164 { "menuOptions.Auto Comment", False },
\r
3165 { "menuOptions.Auto Flag", False },
\r
3166 { "menuOptions.Auto Flip View", False },
\r
3167 { "menuOptions.Auto Observe", False },
\r
3168 { "menuOptions.Auto Raise Board", False },
\r
3169 { "menuOptions.Get Move List", False },
\r
3170 { "menuOptions.ICS Alarm", False },
\r
3171 { "menuOptions.Move Sound", False },
\r
3172 { "menuOptions.Quiet Play", False },
\r
3173 { "menuOptions.Hide Thinking", False },
\r
3174 { "menuOptions.Periodic Updates", False },
\r
3175 { "menuOptions.Ponder Next Move", False },
\r
3176 { "menuHelp.Hint", False },
\r
3177 { "menuHelp.Book", False },
\r
3181 Enables gnuEnables[] = {
\r
3182 { "menuMode.ICS Client", False },
\r
3183 { "menuMode.ICS Input Box", False },
\r
3184 { "menuAction.Accept", False },
\r
3185 { "menuAction.Decline", False },
\r
3186 { "menuAction.Rematch", False },
\r
3187 { "menuAction.Adjourn", False },
\r
3188 { "menuAction.Stop Examining", False },
\r
3189 { "menuAction.Stop Observing", False },
\r
3190 { "menuStep.Revert", False },
\r
3191 { "menuOptions.Auto Comment", False },
\r
3192 { "menuOptions.Auto Observe", False },
\r
3193 { "menuOptions.Auto Raise Board", False },
\r
3194 { "menuOptions.Get Move List", False },
\r
3195 { "menuOptions.Premove", False },
\r
3196 { "menuOptions.Quiet Play", False },
\r
3198 /* The next two options rely on SetCmailMode being called *after* */
\r
3199 /* SetGNUMode so that when GNU is being used to give hints these */
\r
3200 /* menu options are still available */
\r
3202 { "menuFile.Mail Move", False },
\r
3203 { "menuFile.Reload CMail Message", False },
\r
3207 Enables cmailEnables[] = {
\r
3208 { "Action", True },
\r
3209 { "menuAction.Call Flag", False },
\r
3210 { "menuAction.Draw", True },
\r
3211 { "menuAction.Adjourn", False },
\r
3212 { "menuAction.Abort", False },
\r
3213 { "menuAction.Stop Observing", False },
\r
3214 { "menuAction.Stop Examining", False },
\r
3215 { "menuFile.Mail Move", True },
\r
3216 { "menuFile.Reload CMail Message", True },
\r
3220 Enables trainingOnEnables[] = {
\r
3221 { "menuMode.Edit Comment", False },
\r
3222 { "menuMode.Pause", False },
\r
3223 { "menuStep.Forward", False },
\r
3224 { "menuStep.Backward", False },
\r
3225 { "menuStep.Forward to End", False },
\r
3226 { "menuStep.Back to Start", False },
\r
3227 { "menuStep.Move Now", False },
\r
3228 { "menuStep.Truncate Game", False },
\r
3232 Enables trainingOffEnables[] = {
\r
3233 { "menuMode.Edit Comment", True },
\r
3234 { "menuMode.Pause", True },
\r
3235 { "menuStep.Forward", True },
\r
3236 { "menuStep.Backward", True },
\r
3237 { "menuStep.Forward to End", True },
\r
3238 { "menuStep.Back to Start", True },
\r
3239 { "menuStep.Move Now", True },
\r
3240 { "menuStep.Truncate Game", True },
\r
3244 Enables machineThinkingEnables[] = {
\r
3245 { "menuFile.Load Game", False },
\r
3246 { "menuFile.Load Next Game", False },
\r
3247 { "menuFile.Load Previous Game", False },
\r
3248 { "menuFile.Reload Same Game", False },
\r
3249 { "menuFile.Paste Game", False },
\r
3250 { "menuFile.Load Position", False },
\r
3251 { "menuFile.Load Next Position", False },
\r
3252 { "menuFile.Load Previous Position", False },
\r
3253 { "menuFile.Reload Same Position", False },
\r
3254 { "menuFile.Paste Position", False },
\r
3255 { "menuMode.Machine White", False },
\r
3256 { "menuMode.Machine Black", False },
\r
3257 { "menuMode.Two Machines", False },
\r
3258 { "menuStep.Retract Move", False },
\r
3262 Enables userThinkingEnables[] = {
\r
3263 { "menuFile.Load Game", True },
\r
3264 { "menuFile.Load Next Game", True },
\r
3265 { "menuFile.Load Previous Game", True },
\r
3266 { "menuFile.Reload Same Game", True },
\r
3267 { "menuFile.Paste Game", True },
\r
3268 { "menuFile.Load Position", True },
\r
3269 { "menuFile.Load Next Position", True },
\r
3270 { "menuFile.Load Previous Position", True },
\r
3271 { "menuFile.Reload Same Position", True },
\r
3272 { "menuFile.Paste Position", True },
\r
3273 { "menuMode.Machine White", True },
\r
3274 { "menuMode.Machine Black", True },
\r
3275 { "menuMode.Two Machines", True },
\r
3276 { "menuStep.Retract Move", True },
\r
3282 SetMenuEnables(icsEnables);
\r
3285 if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */
\r
3286 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
\r
3293 SetMenuEnables(ncpEnables);
\r
3299 SetMenuEnables(gnuEnables);
\r
3305 SetMenuEnables(cmailEnables);
\r
3309 SetTrainingModeOn()
\r
3311 SetMenuEnables(trainingOnEnables);
\r
3312 if (appData.showButtonBar) {
\r
3313 XtSetSensitive(buttonBarWidget, False);
\r
3319 SetTrainingModeOff()
\r
3321 SetMenuEnables(trainingOffEnables);
\r
3322 if (appData.showButtonBar) {
\r
3323 XtSetSensitive(buttonBarWidget, True);
\r
3328 SetUserThinkingEnables()
\r
3330 if (appData.noChessProgram) return;
\r
3331 SetMenuEnables(userThinkingEnables);
\r
3335 SetMachineThinkingEnables()
\r
3337 if (appData.noChessProgram) return;
\r
3338 SetMenuEnables(machineThinkingEnables);
\r
3339 switch (gameMode) {
\r
3340 case MachinePlaysBlack:
\r
3341 case MachinePlaysWhite:
\r
3342 case TwoMachinesPlay:
\r
3343 XtSetSensitive(XtNameToWidget(menuBarWidget,
\r
3344 ModeToWidgetName(gameMode)), True);
\r
3351 #define Abs(n) ((n)<0 ? -(n) : (n))
\r
3354 * Find a font that matches "pattern" that is as close as
\r
3355 * possible to the targetPxlSize. Prefer fonts that are k
\r
3356 * pixels smaller to fonts that are k pixels larger. The
\r
3357 * pattern must be in the X Consortium standard format,
\r
3358 * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
\r
3359 * The return value should be freed with XtFree when no
\r
3362 char *FindFont(pattern, targetPxlSize)
\r
3364 int targetPxlSize;
\r
3366 char **fonts, *p, *best, *scalable, *scalableTail;
\r
3367 int i, j, nfonts, minerr, err, pxlSize;
\r
3370 char **missing_list;
\r
3371 int missing_count;
\r
3372 char *def_string, *base_fnt_lst, strInt[3];
\r
3374 XFontStruct **fnt_list;
\r
3376 base_fnt_lst = calloc(1, strlen(pattern) + 3);
\r
3377 sprintf(strInt, "%d", targetPxlSize);
\r
3378 p = strstr(pattern, "--");
\r
3379 strncpy(base_fnt_lst, pattern, p - pattern + 2);
\r
3380 strcat(base_fnt_lst, strInt);
\r
3381 strcat(base_fnt_lst, strchr(p + 2, '-'));
\r
3383 if ((fntSet = XCreateFontSet(xDisplay,
\r
3387 &def_string)) == NULL) {
\r
3389 fprintf(stderr, _("Unable to create font set.\n"));
\r
3393 nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
\r
3395 fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
\r
3397 fprintf(stderr, _("%s: no fonts match pattern %s\n"),
\r
3398 programName, pattern);
\r
3406 for (i=0; i<nfonts; i++) {
\r
3409 if (*p != '-') continue;
\r
3411 if (*p == NULLCHAR) break;
\r
3412 if (*p++ == '-') j++;
\r
3414 if (j < 7) continue;
\r
3415 pxlSize = atoi(p);
\r
3416 if (pxlSize == 0) {
\r
3417 scalable = fonts[i];
\r
3420 err = pxlSize - targetPxlSize;
\r
3421 if (Abs(err) < Abs(minerr) ||
\r
3422 (minerr > 0 && err < 0 && -err == minerr)) {
\r
3428 if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
\r
3429 /* If the error is too big and there is a scalable font,
\r
3430 use the scalable font. */
\r
3431 int headlen = scalableTail - scalable;
\r
3432 p = (char *) XtMalloc(strlen(scalable) + 10);
\r
3433 while (isdigit(*scalableTail)) scalableTail++;
\r
3434 sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
\r
3436 p = (char *) XtMalloc(strlen(best) + 1);
\r
3439 if (appData.debugMode) {
\r
3440 fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"),
\r
3441 pattern, targetPxlSize, p);
\r
3444 if (missing_count > 0)
\r
3445 XFreeStringList(missing_list);
\r
3446 XFreeFontSet(xDisplay, fntSet);
\r
3448 XFreeFontNames(fonts);
\r
3455 XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
\r
3456 | GCBackground | GCFunction | GCPlaneMask;
\r
3457 XGCValues gc_values;
\r
3458 GC copyInvertedGC;
\r
3460 gc_values.plane_mask = AllPlanes;
\r
3461 gc_values.line_width = lineGap;
\r
3462 gc_values.line_style = LineSolid;
\r
3463 gc_values.function = GXcopy;
\r
3465 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3466 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3467 lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3469 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3470 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3471 coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3472 XSetFont(xDisplay, coordGC, coordFontID);
\r
3474 // [HGM] make font for holdings counts (white on black0
\r
3475 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3476 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3477 countGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3478 XSetFont(xDisplay, countGC, countFontID);
\r
3480 if (appData.monoMode) {
\r
3481 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3482 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3483 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3485 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
\r
3486 gc_values.background = XBlackPixel(xDisplay, xScreen);
\r
3487 lightSquareGC = wbPieceGC
\r
3488 = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3490 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
\r
3491 gc_values.background = XWhitePixel(xDisplay, xScreen);
\r
3492 darkSquareGC = bwPieceGC
\r
3493 = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3495 if (DefaultDepth(xDisplay, xScreen) == 1) {
\r
3496 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
\r
3497 gc_values.function = GXcopyInverted;
\r
3498 copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3499 gc_values.function = GXcopy;
\r
3500 if (XBlackPixel(xDisplay, xScreen) == 1) {
\r
3501 bwPieceGC = darkSquareGC;
\r
3502 wbPieceGC = copyInvertedGC;
\r
3504 bwPieceGC = copyInvertedGC;
\r
3505 wbPieceGC = lightSquareGC;
\r
3509 gc_values.foreground = highlightSquareColor;
\r
3510 gc_values.background = highlightSquareColor;
\r
3511 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3513 gc_values.foreground = premoveHighlightColor;
\r
3514 gc_values.background = premoveHighlightColor;
\r
3515 prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3517 gc_values.foreground = lightSquareColor;
\r
3518 gc_values.background = darkSquareColor;
\r
3519 lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3521 gc_values.foreground = darkSquareColor;
\r
3522 gc_values.background = lightSquareColor;
\r
3523 darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3525 gc_values.foreground = jailSquareColor;
\r
3526 gc_values.background = jailSquareColor;
\r
3527 jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3529 gc_values.foreground = whitePieceColor;
\r
3530 gc_values.background = darkSquareColor;
\r
3531 wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3533 gc_values.foreground = whitePieceColor;
\r
3534 gc_values.background = lightSquareColor;
\r
3535 wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3537 gc_values.foreground = whitePieceColor;
\r
3538 gc_values.background = jailSquareColor;
\r
3539 wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3541 gc_values.foreground = blackPieceColor;
\r
3542 gc_values.background = darkSquareColor;
\r
3543 bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3545 gc_values.foreground = blackPieceColor;
\r
3546 gc_values.background = lightSquareColor;
\r
3547 blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3549 gc_values.foreground = blackPieceColor;
\r
3550 gc_values.background = jailSquareColor;
\r
3551 bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
\r
3555 void loadXIM(xim, xmask, filename, dest, mask)
\r
3562 int x, y, w, h, p;
\r
3568 fp = fopen(filename, "rb");
\r
3570 fprintf(stderr, _("%s: error loading XIM!\n"), programName);
\r
3577 for (y=0; y<h; ++y) {
\r
3578 for (x=0; x<h; ++x) {
\r
3583 XPutPixel(xim, x, y, blackPieceColor);
\r
3585 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
\r
3588 XPutPixel(xim, x, y, darkSquareColor);
\r
3590 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
\r
3593 XPutPixel(xim, x, y, whitePieceColor);
\r
3595 XPutPixel(xmask, x, y, WhitePixel(xDisplay,xScreen));
\r
3598 XPutPixel(xim, x, y, lightSquareColor);
\r
3600 XPutPixel(xmask, x, y, BlackPixel(xDisplay,xScreen));
\r
3606 /* create Pixmap of piece */
\r
3607 *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3608 w, h, xim->depth);
\r
3609 XPutImage(xDisplay, *dest, lightSquareGC, xim,
\r
3610 0, 0, 0, 0, w, h);
\r
3612 /* create Pixmap of clipmask
\r
3613 Note: We assume the white/black pieces have the same
\r
3614 outline, so we make only 6 masks. This is okay
\r
3615 since the XPM clipmask routines do the same. */
\r
3617 temp = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3618 w, h, xim->depth);
\r
3619 XPutImage(xDisplay, temp, lightSquareGC, xmask,
\r
3620 0, 0, 0, 0, w, h);
\r
3622 /* now create the 1-bit version */
\r
3623 *mask = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay),
\r
3626 values.foreground = 1;
\r
3627 values.background = 0;
\r
3629 /* Don't use XtGetGC, not read only */
\r
3630 maskGC = XCreateGC(xDisplay, *mask,
\r
3631 GCForeground | GCBackground, &values);
\r
3632 XCopyPlane(xDisplay, temp, *mask, maskGC,
\r
3633 0, 0, squareSize, squareSize, 0, 0, 1);
\r
3634 XFreePixmap(xDisplay, temp);
\r
3638 void CreateXIMPieces()
\r
3641 char buf[MSG_SIZ];
\r
3643 static char *ximkind[] = { "ll", "ld", "dl", "dd" };
\r
3648 /* The XSynchronize calls were copied from CreatePieces.
\r
3649 Not sure if needed, but can't hurt */
\r
3650 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3653 /* temp needed by loadXIM() */
\r
3654 ximtemp = XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3655 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3657 if (strlen(appData.pixmapDirectory) == 0) {
\r
3661 if (appData.monoMode) {
\r
3662 DisplayFatalError(_("XIM pieces cannot be used in monochrome mode"),
\r
3666 fprintf(stderr, _("\nLoading XIMs...\n"));
\r
3668 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3669 fprintf(stderr, "%d", piece+1);
\r
3670 for (kind=0; kind<4; kind++) {
\r
3671 fprintf(stderr, ".");
\r
3672 sprintf(buf, "%s/%c%s%u.xim",
\r
3673 ExpandPathName(appData.pixmapDirectory),
\r
3674 ToLower(PieceToChar((ChessSquare)piece)),
\r
3675 ximkind[kind], ss);
\r
3676 ximPieceBitmap[kind][piece] =
\r
3677 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3678 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3679 if (appData.debugMode)
\r
3680 fprintf(stderr, _("(File:%s:) "), buf);
\r
3681 loadXIM(ximPieceBitmap[kind][piece],
\r
3683 &(xpmPieceBitmap[kind][piece]),
\r
3684 &(ximMaskPm[piece%(int)BlackPawn]));
\r
3686 fprintf(stderr," ");
\r
3688 /* Load light and dark squares */
\r
3689 /* If the LSQ and DSQ pieces don't exist, we will
\r
3690 draw them with solid squares. */
\r
3691 sprintf(buf, "%s/lsq%u.xim", ExpandPathName(appData.pixmapDirectory), ss);
\r
3692 if (access(buf, 0) != 0) {
\r
3696 fprintf(stderr, _("light square "));
\r
3698 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3699 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3700 if (appData.debugMode)
\r
3701 fprintf(stderr, _("(File:%s:) "), buf);
\r
3703 loadXIM(ximLightSquare, NULL, buf, &xpmLightSquare, NULL);
\r
3704 fprintf(stderr, _("dark square "));
\r
3705 sprintf(buf, "%s/dsq%u.xim",
\r
3706 ExpandPathName(appData.pixmapDirectory), ss);
\r
3707 if (appData.debugMode)
\r
3708 fprintf(stderr, _("(File:%s:) "), buf);
\r
3710 XGetImage(xDisplay, DefaultRootWindow(xDisplay),
\r
3711 0, 0, ss, ss, AllPlanes, XYPixmap);
\r
3712 loadXIM(ximDarkSquare, NULL, buf, &xpmDarkSquare, NULL);
\r
3713 xpmJailSquare = xpmLightSquare;
\r
3715 fprintf(stderr, _("Done.\n"));
\r
3717 XSynchronize(xDisplay, False); /* Work-around for xlib/xt buffering bug */
\r
3721 void CreateXPMPieces()
\r
3723 int piece, kind, r;
\r
3724 char buf[MSG_SIZ];
\r
3725 u_int ss = squareSize;
\r
3726 XpmAttributes attr;
\r
3727 static char *xpmkind[] = { "ll", "ld", "dl", "dd" };
\r
3728 XpmColorSymbol symbols[4];
\r
3731 /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */
\r
3732 if (appData.debugMode) {
\r
3733 fprintf(stderr, "XPM Library Version: %d.%d%c\n",
\r
3734 XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1));
\r
3738 /* The XSynchronize calls were copied from CreatePieces.
\r
3739 Not sure if needed, but can't hurt */
\r
3740 XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */
\r
3742 /* Setup translations so piece colors match square colors */
\r
3743 symbols[0].name = "light_piece";
\r
3744 symbols[0].value = appData.whitePieceColor;
\r
3745 symbols[1].name = "dark_piece";
\r
3746 symbols[1].value = appData.blackPieceColor;
\r
3747 symbols[2].name = "light_square";
\r
3748 symbols[2].value = appData.lightSquareColor;
\r
3749 symbols[3].name = "dark_square";
\r
3750 symbols[3].value = appData.darkSquareColor;
\r
3752 attr.valuemask = XpmColorSymbols;
\r
3753 attr.colorsymbols = symbols;
\r
3754 attr.numsymbols = 4;
\r
3756 if (appData.monoMode) {
\r
3757 DisplayFatalError(_("XPM pieces cannot be used in monochrome mode"),
\r
3761 if (strlen(appData.pixmapDirectory) == 0) {
\r
3762 XpmPieces* pieces = builtInXpms;
\r
3765 while (pieces->size != squareSize && pieces->size) pieces++;
\r
3766 if (!pieces->size) {
\r
3767 fprintf(stderr, _("No builtin XPM pieces of size %d\n"), squareSize);
\r
3770 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3771 for (kind=0; kind<4; kind++) {
\r
3773 if ((r=XpmCreatePixmapFromData(xDisplay, xBoardWindow,
\r
3774 pieces->xpm[piece][kind],
\r
3775 &(xpmPieceBitmap[kind][piece]),
\r
3776 NULL, &attr)) != 0) {
\r
3777 fprintf(stderr, _("Error %d loading XPM image \"%s\"\n"),
\r
3784 xpmJailSquare = xpmLightSquare;
\r
3788 fprintf(stderr, _("\nLoading XPMs...\n"));
\r
3791 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3792 fprintf(stderr, "%d ", piece+1);
\r
3793 for (kind=0; kind<4; kind++) {
\r
3794 sprintf(buf, "%s/%c%s%u.xpm",
\r
3795 ExpandPathName(appData.pixmapDirectory),
\r
3796 ToLower(PieceToChar((ChessSquare)piece)),
\r
3797 xpmkind[kind], ss);
\r
3798 if (appData.debugMode) {
\r
3799 fprintf(stderr, _("(File:%s:) "), buf);
\r
3801 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3802 &(xpmPieceBitmap[kind][piece]),
\r
3803 NULL, &attr)) != 0) {
\r
3804 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"),
\r
3810 /* Load light and dark squares */
\r
3811 /* If the LSQ and DSQ pieces don't exist, we will
\r
3812 draw them with solid squares. */
\r
3813 fprintf(stderr, _("light square "));
\r
3814 sprintf(buf, "%s/lsq%u.xpm", ExpandPathName(appData.pixmapDirectory), ss);
\r
3815 if (access(buf, 0) != 0) {
\r
3819 if (appData.debugMode)
\r
3820 fprintf(stderr, _("(File:%s:) "), buf);
\r
3822 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3823 &xpmLightSquare, NULL, &attr)) != 0) {
\r
3824 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
\r
3827 fprintf(stderr, _("dark square "));
\r
3828 sprintf(buf, "%s/dsq%u.xpm",
\r
3829 ExpandPathName(appData.pixmapDirectory), ss);
\r
3830 if (appData.debugMode) {
\r
3831 fprintf(stderr, _("(File:%s:) "), buf);
\r
3833 if ((r=XpmReadFileToPixmap(xDisplay, xBoardWindow, buf,
\r
3834 &xpmDarkSquare, NULL, &attr)) != 0) {
\r
3835 fprintf(stderr, _("Error %d loading XPM file \"%s\"\n"), r, buf);
\r
3839 xpmJailSquare = xpmLightSquare;
\r
3840 fprintf(stderr, _("Done.\n"));
\r
3842 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3845 #endif /* HAVE_LIBXPM */
\r
3848 /* No built-in bitmaps */
\r
3849 void CreatePieces()
\r
3852 char buf[MSG_SIZ];
\r
3853 u_int ss = squareSize;
\r
3855 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3858 for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
\r
3859 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3860 sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
\r
3861 ss, kind == SOLID ? 's' : 'o');
\r
3862 ReadBitmap(&pieceBitmap[kind][piece], buf, NULL, ss, ss);
\r
3866 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3870 /* With built-in bitmaps */
\r
3871 void CreatePieces()
\r
3873 BuiltInBits* bib = builtInBits;
\r
3875 char buf[MSG_SIZ];
\r
3876 u_int ss = squareSize;
\r
3878 XSynchronize(xDisplay, True); /* Work-around for xlib/xt
\r
3881 while (bib->squareSize != ss && bib->squareSize != 0) bib++;
\r
3883 for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
\r
3884 for (piece = (int) WhitePawn; piece <= (int) WhiteKing; piece++) {
\r
3885 sprintf(buf, "%c%u%c.bm", ToLower(PieceToChar((ChessSquare)piece)),
\r
3886 ss, kind == SOLID ? 's' : 'o');
\r
3887 ReadBitmap(&pieceBitmap[kind][piece], buf,
\r
3888 bib->bits[kind][piece], ss, ss);
\r
3892 XSynchronize(xDisplay, False); /* Work-around for xlib/xt
\r
3897 void ReadBitmap(pm, name, bits, wreq, hreq)
\r
3900 unsigned char bits[];
\r
3906 char msg[MSG_SIZ], fullname[MSG_SIZ];
\r
3908 if (*appData.bitmapDirectory != NULLCHAR) {
\r
3909 strcpy(fullname, appData.bitmapDirectory);
\r
3910 strcat(fullname, "/");
\r
3911 strcat(fullname, name);
\r
3912 errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
\r
3913 &w, &h, pm, &x_hot, &y_hot);
\r
3914 if (errcode != BitmapSuccess) {
\r
3915 switch (errcode) {
\r
3916 case BitmapOpenFailed:
\r
3917 sprintf(msg, _("Can't open bitmap file %s"), fullname);
\r
3919 case BitmapFileInvalid:
\r
3920 sprintf(msg, _("Invalid bitmap in file %s"), fullname);
\r
3922 case BitmapNoMemory:
\r
3923 sprintf(msg, _("Ran out of memory reading bitmap file %s"),
\r
3927 sprintf(msg, _("Unknown XReadBitmapFile error %d on file %s"),
\r
3928 errcode, fullname);
\r
3931 fprintf(stderr, _("%s: %s...using built-in\n"),
\r
3932 programName, msg);
\r
3933 } else if (w != wreq || h != hreq) {
\r
3935 _("%s: Bitmap %s is %dx%d, not %dx%d...using built-in\n"),
\r
3936 programName, fullname, w, h, wreq, hreq);
\r
3941 if (bits == NULL) {
\r
3943 fprintf(stderr, _("%s: No built-in bitmap for %s; giving up\n"),
\r
3944 programName, name);
\r
3947 ; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
\r
3949 *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
\r
3958 if (lineGap == 0) return;
\r
3960 /* [HR] Split this into 2 loops for non-square boards. */
\r
3962 for (i = 0; i < BOARD_HEIGHT + 1; i++) {
\r
3963 gridSegments[i].x1 = 0;
\r
3964 gridSegments[i].x2 =
\r
3965 lineGap + BOARD_WIDTH * (squareSize + lineGap);
\r
3966 gridSegments[i].y1 = gridSegments[i].y2
\r
3967 = lineGap / 2 + (i * (squareSize + lineGap));
\r
3970 for (j = 0; j < BOARD_WIDTH + 1; j++) {
\r
3971 gridSegments[j + i].y1 = 0;
\r
3972 gridSegments[j + i].y2 =
\r
3973 lineGap + BOARD_HEIGHT * (squareSize + lineGap);
\r
3974 gridSegments[j + i].x1 = gridSegments[j + i].x2
\r
3975 = lineGap / 2 + (j * (squareSize + lineGap));
\r
3979 static void MenuBarSelect(w, addr, index)
\r
3984 XtActionProc proc = (XtActionProc) addr;
\r
3986 (proc)(NULL, NULL, NULL, NULL);
\r
3989 void CreateMenuBarPopup(parent, name, mb)
\r
3995 Widget menu, entry;
\r
3999 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
\r
4002 XtSetArg(args[j], XtNleftMargin, 20); j++;
\r
4003 XtSetArg(args[j], XtNrightMargin, 20); j++;
\r
4005 while (mi->string != NULL) {
\r
4006 if (strcmp(mi->string, "----") == 0) {
\r
4007 entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
\r
4010 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
\r
4011 entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
\r
4013 XtAddCallback(entry, XtNcallback,
\r
4014 (XtCallbackProc) MenuBarSelect,
\r
4015 (caddr_t) mi->proc);
\r
4021 Widget CreateMenuBar(mb)
\r
4025 Widget anchor, menuBar;
\r
4027 char menuName[MSG_SIZ];
\r
4030 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
\r
4031 XtSetArg(args[j], XtNvSpace, 0); j++;
\r
4032 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4033 menuBar = XtCreateWidget("menuBar", boxWidgetClass,
\r
4034 formWidget, args, j);
\r
4036 while (mb->name != NULL) {
\r
4037 strcpy(menuName, "menu");
\r
4038 strcat(menuName, mb->name);
\r
4040 XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;
\r
4042 char shortName[2];
\r
4043 shortName[0] = _(mb->name)[0];
\r
4044 shortName[1] = NULLCHAR;
\r
4045 XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
\r
4048 XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++;
\r
4051 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4052 anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
\r
4053 menuBar, args, j);
\r
4054 CreateMenuBarPopup(menuBar, menuName, mb);
\r
4060 Widget CreateButtonBar(mi)
\r
4064 Widget button, buttonBar;
\r
4068 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
\r
4070 XtSetArg(args[j], XtNhSpace, 0); j++;
\r
4072 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4073 XtSetArg(args[j], XtNvSpace, 0); j++;
\r
4074 buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
\r
4075 formWidget, args, j);
\r
4077 while (mi->string != NULL) {
\r
4080 XtSetArg(args[j], XtNinternalWidth, 2); j++;
\r
4081 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
4083 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
\r
4084 button = XtCreateManagedWidget(mi->string, commandWidgetClass,
\r
4085 buttonBar, args, j);
\r
4086 XtAddCallback(button, XtNcallback,
\r
4087 (XtCallbackProc) MenuBarSelect,
\r
4088 (caddr_t) mi->proc);
\r
4095 CreatePieceMenu(name, color)
\r
4100 Widget entry, menu;
\r
4102 ChessSquare selection;
\r
4104 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
\r
4105 boardWidget, args, 0);
\r
4107 for (i = 0; i < PIECE_MENU_SIZE; i++) {
\r
4108 String item = pieceMenuStrings[color][i];
\r
4110 if (strcmp(item, "----") == 0) {
\r
4111 entry = XtCreateManagedWidget(item, smeLineObjectClass,
\r
4114 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
\r
4115 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
\r
4117 selection = pieceMenuTranslation[color][i];
\r
4118 XtAddCallback(entry, XtNcallback,
\r
4119 (XtCallbackProc) PieceMenuSelect,
\r
4120 (caddr_t) selection);
\r
4121 if (selection == WhitePawn || selection == BlackPawn) {
\r
4122 XtSetArg(args[0], XtNpopupOnEntry, entry);
\r
4123 XtSetValues(menu, args, 1);
\r
4131 CreatePieceMenus()
\r
4136 ChessSquare selection;
\r
4138 whitePieceMenu = CreatePieceMenu("menuW", 0);
\r
4139 blackPieceMenu = CreatePieceMenu("menuB", 1);
\r
4141 XtRegisterGrabAction(PieceMenuPopup, True,
\r
4142 (unsigned)(ButtonPressMask|ButtonReleaseMask),
\r
4143 GrabModeAsync, GrabModeAsync);
\r
4145 XtSetArg(args[0], XtNlabel, _("Drop"));
\r
4146 dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
\r
4147 boardWidget, args, 1);
\r
4148 for (i = 0; i < DROP_MENU_SIZE; i++) {
\r
4149 String item = dropMenuStrings[i];
\r
4151 if (strcmp(item, "----") == 0) {
\r
4152 entry = XtCreateManagedWidget(item, smeLineObjectClass,
\r
4153 dropMenu, NULL, 0);
\r
4155 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
\r
4156 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
\r
4157 dropMenu, args, 1);
\r
4158 selection = dropMenuTranslation[i];
\r
4159 XtAddCallback(entry, XtNcallback,
\r
4160 (XtCallbackProc) DropMenuSelect,
\r
4161 (caddr_t) selection);
\r
4166 void SetupDropMenu()
\r
4174 for (i=0; i<sizeof(dmEnables)/sizeof(DropMenuEnables); i++) {
\r
4175 entry = XtNameToWidget(dropMenu, dmEnables[i].widget);
\r
4176 p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,
\r
4177 dmEnables[i].piece);
\r
4178 XtSetSensitive(entry, p != NULL || !appData.testLegality
\r
4179 /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse
\r
4180 && !appData.icsActive));
\r
4182 while (p && *p++ == dmEnables[i].piece) count++;
\r
4183 sprintf(label, "%s %d", dmEnables[i].widget, count);
\r
4185 XtSetArg(args[j], XtNlabel, label); j++;
\r
4186 XtSetValues(entry, args, j);
\r
4190 void PieceMenuPopup(w, event, params, num_params)
\r
4194 Cardinal *num_params;
\r
4197 if (event->type != ButtonPress) return;
\r
4198 if (errorUp) ErrorPopDown();
\r
4199 switch (gameMode) {
\r
4200 case EditPosition:
\r
4201 case IcsExamining:
\r
4202 whichMenu = params[0];
\r
4204 case IcsPlayingWhite:
\r
4205 case IcsPlayingBlack:
\r
4207 case MachinePlaysWhite:
\r
4208 case MachinePlaysBlack:
\r
4209 if (appData.testLegality &&
\r
4210 gameInfo.variant != VariantBughouse &&
\r
4211 gameInfo.variant != VariantCrazyhouse) return;
\r
4213 whichMenu = "menuD";
\r
4219 if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||
\r
4220 ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {
\r
4221 pmFromX = pmFromY = -1;
\r
4225 pmFromX = BOARD_WIDTH - 1 - pmFromX;
\r
4227 pmFromY = BOARD_HEIGHT - 1 - pmFromY;
\r
4229 XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
\r
4232 static void PieceMenuSelect(w, piece, junk)
\r
4234 ChessSquare piece;
\r
4237 if (pmFromX < 0 || pmFromY < 0) return;
\r
4238 EditPositionMenuEvent(piece, pmFromX, pmFromY);
\r
4241 static void DropMenuSelect(w, piece, junk)
\r
4243 ChessSquare piece;
\r
4246 if (pmFromX < 0 || pmFromY < 0) return;
\r
4247 DropMenuEvent(piece, pmFromX, pmFromY);
\r
4250 void WhiteClock(w, event, prms, nprms)
\r
4256 if (gameMode == EditPosition || gameMode == IcsExamining) {
\r
4257 SetWhiteToPlayEvent();
\r
4258 } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
\r
4263 void BlackClock(w, event, prms, nprms)
\r
4269 if (gameMode == EditPosition || gameMode == IcsExamining) {
\r
4270 SetBlackToPlayEvent();
\r
4271 } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
\r
4278 * If the user selects on a border boundary, return -1; if off the board,
\r
4279 * return -2. Otherwise map the event coordinate to the square.
\r
4281 int EventToSquare(x, limit)
\r
4289 if ((x % (squareSize + lineGap)) >= squareSize)
\r
4291 x /= (squareSize + lineGap);
\r
4297 static void do_flash_delay(msec)
\r
4298 unsigned long msec;
\r
4303 static void drawHighlight(file, rank, gc)
\r
4309 if (lineGap == 0 || appData.blindfold) return;
\r
4312 x = lineGap/2 + ((BOARD_WIDTH-1)-file) *
\r
4313 (squareSize + lineGap);
\r
4314 y = lineGap/2 + rank * (squareSize + lineGap);
\r
4316 x = lineGap/2 + file * (squareSize + lineGap);
\r
4317 y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) *
\r
4318 (squareSize + lineGap);
\r
4321 XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
\r
4322 squareSize+lineGap, squareSize+lineGap);
\r
4325 int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
\r
4326 int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1;
\r
4329 SetHighlights(fromX, fromY, toX, toY)
\r
4330 int fromX, fromY, toX, toY;
\r
4332 if (hi1X != fromX || hi1Y != fromY) {
\r
4333 if (hi1X >= 0 && hi1Y >= 0) {
\r
4334 drawHighlight(hi1X, hi1Y, lineGC);
\r
4336 if (fromX >= 0 && fromY >= 0) {
\r
4337 drawHighlight(fromX, fromY, highlineGC);
\r
4340 if (hi2X != toX || hi2Y != toY) {
\r
4341 if (hi2X >= 0 && hi2Y >= 0) {
\r
4342 drawHighlight(hi2X, hi2Y, lineGC);
\r
4344 if (toX >= 0 && toY >= 0) {
\r
4345 drawHighlight(toX, toY, highlineGC);
\r
4357 SetHighlights(-1, -1, -1, -1);
\r
4362 SetPremoveHighlights(fromX, fromY, toX, toY)
\r
4363 int fromX, fromY, toX, toY;
\r
4365 if (pm1X != fromX || pm1Y != fromY) {
\r
4366 if (pm1X >= 0 && pm1Y >= 0) {
\r
4367 drawHighlight(pm1X, pm1Y, lineGC);
\r
4369 if (fromX >= 0 && fromY >= 0) {
\r
4370 drawHighlight(fromX, fromY, prelineGC);
\r
4373 if (pm2X != toX || pm2Y != toY) {
\r
4374 if (pm2X >= 0 && pm2Y >= 0) {
\r
4375 drawHighlight(pm2X, pm2Y, lineGC);
\r
4377 if (toX >= 0 && toY >= 0) {
\r
4378 drawHighlight(toX, toY, prelineGC);
\r
4388 ClearPremoveHighlights()
\r
4390 SetPremoveHighlights(-1, -1, -1, -1);
\r
4393 static void BlankSquare(x, y, color, piece, dest)
\r
4395 ChessSquare piece;
\r
4398 if (useImages && useImageSqs) {
\r
4401 case 1: /* light */
\r
4402 pm = xpmLightSquare;
\r
4404 case 0: /* dark */
\r
4405 pm = xpmDarkSquare;
\r
4407 case 2: /* neutral */
\r
4409 pm = xpmJailSquare;
\r
4412 XCopyArea(xDisplay, pm, dest, wlPieceGC, 0, 0,
\r
4413 squareSize, squareSize, x, y);
\r
4417 case 1: /* light */
\r
4418 gc = lightSquareGC;
\r
4420 case 0: /* dark */
\r
4421 gc = darkSquareGC;
\r
4423 case 2: /* neutral */
\r
4425 gc = jailSquareGC;
\r
4428 XFillRectangle(xDisplay, dest, gc, x, y, squareSize, squareSize);
\r
4433 I split out the routines to draw a piece so that I could
\r
4434 make a generic flash routine.
\r
4436 static void monoDrawPiece_1bit(piece, square_color, x, y, dest)
\r
4437 ChessSquare piece;
\r
4438 int square_color, x, y;
\r
4441 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
\r
4442 switch (square_color) {
\r
4443 case 1: /* light */
\r
4444 case 2: /* neutral */
\r
4446 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
\r
4447 ? *pieceToOutline(piece)
\r
4448 : *pieceToSolid(piece),
\r
4449 dest, bwPieceGC, 0, 0,
\r
4450 squareSize, squareSize, x, y);
\r
4452 case 0: /* dark */
\r
4453 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
\r
4454 ? *pieceToSolid(piece)
\r
4455 : *pieceToOutline(piece),
\r
4456 dest, wbPieceGC, 0, 0,
\r
4457 squareSize, squareSize, x, y);
\r
4462 static void monoDrawPiece(piece, square_color, x, y, dest)
\r
4463 ChessSquare piece;
\r
4464 int square_color, x, y;
\r
4467 switch (square_color) {
\r
4468 case 1: /* light */
\r
4469 case 2: /* neutral */
\r
4471 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
\r
4472 ? *pieceToOutline(piece)
\r
4473 : *pieceToSolid(piece),
\r
4474 dest, bwPieceGC, 0, 0,
\r
4475 squareSize, squareSize, x, y, 1);
\r
4477 case 0: /* dark */
\r
4478 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
\r
4479 ? *pieceToSolid(piece)
\r
4480 : *pieceToOutline(piece),
\r
4481 dest, wbPieceGC, 0, 0,
\r
4482 squareSize, squareSize, x, y, 1);
\r
4487 static void colorDrawPiece(piece, square_color, x, y, dest)
\r
4488 ChessSquare piece;
\r
4489 int square_color, x, y;
\r
4492 if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
\r
4493 switch (square_color) {
\r
4494 case 1: /* light */
\r
4495 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4496 dest, (int) piece < (int) BlackPawn
\r
4497 ? wlPieceGC : blPieceGC, 0, 0,
\r
4498 squareSize, squareSize, x, y, 1);
\r
4500 case 0: /* dark */
\r
4501 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4502 dest, (int) piece < (int) BlackPawn
\r
4503 ? wdPieceGC : bdPieceGC, 0, 0,
\r
4504 squareSize, squareSize, x, y, 1);
\r
4506 case 2: /* neutral */
\r
4508 XCopyPlane(xDisplay, *pieceToSolid(piece),
\r
4509 dest, (int) piece < (int) BlackPawn
\r
4510 ? wjPieceGC : bjPieceGC, 0, 0,
\r
4511 squareSize, squareSize, x, y, 1);
\r
4516 static void colorDrawPieceImage(piece, square_color, x, y, dest)
\r
4517 ChessSquare piece;
\r
4518 int square_color, x, y;
\r
4523 switch (square_color) {
\r
4524 case 1: /* light */
\r
4525 case 2: /* neutral */
\r
4527 if ((int)piece < (int) BlackPawn) {
\r
4531 piece -= BlackPawn;
\r
4534 case 0: /* dark */
\r
4535 if ((int)piece < (int) BlackPawn) {
\r
4539 piece -= BlackPawn;
\r
4543 XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
\r
4544 dest, wlPieceGC, 0, 0,
\r
4545 squareSize, squareSize, x, y);
\r
4548 typedef void (*DrawFunc)();
\r
4550 DrawFunc ChooseDrawFunc()
\r
4552 if (appData.monoMode) {
\r
4553 if (DefaultDepth(xDisplay, xScreen) == 1) {
\r
4554 return monoDrawPiece_1bit;
\r
4556 return monoDrawPiece;
\r
4560 return colorDrawPieceImage;
\r
4562 return colorDrawPiece;
\r
4566 /* [HR] determine square color depending on chess variant. */
\r
4567 static int SquareColor(row, column)
\r
4572 if (gameInfo.variant == VariantXiangqi) {
\r
4573 if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {
\r
4575 } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {
\r
4577 } else if (row <= 4) {
\r
4583 square_color = ((column + row) % 2) == 1;
\r
4586 /* [hgm] holdings: next line makes all holdings squares light */
\r
4587 if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1;
\r
4589 return square_color;
\r
4592 void DrawSquare(row, column, piece, do_flash)
\r
4593 int row, column, do_flash;
\r
4594 ChessSquare piece;
\r
4596 int square_color, x, y, direction, font_ascent, font_descent;
\r
4599 XCharStruct overall;
\r
4600 DrawFunc drawfunc;
\r
4603 if(gameInfo.variant == VariantShogi) { // [HGM] shogi: in shogi Q is used for Lance
\r
4604 if(piece == WhiteQueen) piece = WhiteLance; else
\r
4605 if(piece == BlackQueen) piece = BlackLance;
\r
4608 else if(gameInfo.variant == VariantGothic) { // [HGM] shogi: in Gothic Chancelor has alternative look
\r
4609 if(piece == WhiteMarshall) piece = WhiteSilver; else
\r
4610 if(piece == BlackMarshall) piece = BlackSilver;
\r
4614 /* Calculate delay in milliseconds (2-delays per complete flash) */
\r
4615 flash_delay = 500 / appData.flashRate;
\r
4618 x = lineGap + ((BOARD_WIDTH-1)-column) *
\r
4619 (squareSize + lineGap);
\r
4620 y = lineGap + row * (squareSize + lineGap);
\r
4622 x = lineGap + column * (squareSize + lineGap);
\r
4623 y = lineGap + ((BOARD_HEIGHT-1)-row) *
\r
4624 (squareSize + lineGap);
\r
4627 square_color = SquareColor(row, column);
\r
4629 if ( // [HGM] holdings: blank out area between board and holdings
\r
4630 column == BOARD_LEFT-1 || column == BOARD_RGHT
\r
4631 || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)
\r
4632 || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {
\r
4633 BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
\r
4635 // [HGM] print piece counts next to holdings
\r
4636 string[1] = NULLCHAR;
\r
4637 if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) {
\r
4638 string[0] = '0' + piece;
\r
4639 XTextExtents(countFontStruct, string, 1, &direction,
\r
4640 &font_ascent, &font_descent, &overall);
\r
4641 if (appData.monoMode) {
\r
4642 XDrawImageString(xDisplay, xBoardWindow, countGC,
\r
4643 x + squareSize - overall.width - 2,
\r
4644 y + font_ascent + 1, string, 1);
\r
4646 XDrawString(xDisplay, xBoardWindow, countGC,
\r
4647 x + squareSize - overall.width - 2,
\r
4648 y + font_ascent + 1, string, 1);
\r
4651 if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) {
\r
4652 string[0] = '0' + piece;
\r
4653 XTextExtents(countFontStruct, string, 1, &direction,
\r
4654 &font_ascent, &font_descent, &overall);
\r
4655 if (appData.monoMode) {
\r
4656 XDrawImageString(xDisplay, xBoardWindow, countGC,
\r
4657 x + 2, y + font_ascent + 1, string, 1);
\r
4659 XDrawString(xDisplay, xBoardWindow, countGC,
\r
4660 x + 2, y + font_ascent + 1, string, 1);
\r
4664 if (piece == EmptySquare || appData.blindfold) {
\r
4665 BlankSquare(x, y, square_color, piece, xBoardWindow);
\r
4667 drawfunc = ChooseDrawFunc();
\r
4668 if (do_flash && appData.flashCount > 0) {
\r
4669 for (i=0; i<appData.flashCount; ++i) {
\r
4671 drawfunc(piece, square_color, x, y, xBoardWindow);
\r
4672 XSync(xDisplay, False);
\r
4673 do_flash_delay(flash_delay);
\r
4675 BlankSquare(x, y, square_color, piece, xBoardWindow);
\r
4676 XSync(xDisplay, False);
\r
4677 do_flash_delay(flash_delay);
\r
4680 drawfunc(piece, square_color, x, y, xBoardWindow);
\r
4684 string[1] = NULLCHAR;
\r
4685 if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)
\r
4686 && column >= BOARD_LEFT && column < BOARD_RGHT) {
\r
4687 string[0] = 'a' + column - BOARD_LEFT;
\r
4688 XTextExtents(coordFontStruct, string, 1, &direction,
\r
4689 &font_ascent, &font_descent, &overall);
\r
4690 if (appData.monoMode) {
\r
4691 XDrawImageString(xDisplay, xBoardWindow, coordGC,
\r
4692 x + squareSize - overall.width - 2,
\r
4693 y + squareSize - font_descent - 1, string, 1);
\r
4695 XDrawString(xDisplay, xBoardWindow, coordGC,
\r
4696 x + squareSize - overall.width - 2,
\r
4697 y + squareSize - font_descent - 1, string, 1);
\r
4700 if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) {
\r
4701 string[0] = ONE + row;
\r
4702 XTextExtents(coordFontStruct, string, 1, &direction,
\r
4703 &font_ascent, &font_descent, &overall);
\r
4704 if (appData.monoMode) {
\r
4705 XDrawImageString(xDisplay, xBoardWindow, coordGC,
\r
4706 x + 2, y + font_ascent + 1, string, 1);
\r
4708 XDrawString(xDisplay, xBoardWindow, coordGC,
\r
4709 x + 2, y + font_ascent + 1, string, 1);
\r
4715 /* Why is this needed on some versions of X? */
\r
4716 void EventProc(widget, unused, event)
\r
4721 if (!XtIsRealized(widget))
\r
4724 switch (event->type) {
\r
4726 if (event->xexpose.count > 0) return; /* no clipping is done */
\r
4727 XDrawPosition(widget, True, NULL);
\r
4735 void DrawPosition(fullRedraw, board)
\r
4736 /*Boolean*/int fullRedraw;
\r
4739 XDrawPosition(boardWidget, fullRedraw, board);
\r
4742 /* Returns 1 if there are "too many" differences between b1 and b2
\r
4743 (i.e. more than 1 move was made) */
\r
4744 static int too_many_diffs(b1, b2)
\r
4750 for (i=0; i<BOARD_HEIGHT; ++i) {
\r
4751 for (j=0; j<BOARD_WIDTH; ++j) {
\r
4752 if (b1[i][j] != b2[i][j]) {
\r
4753 if (++c > 4) /* Castling causes 4 diffs */
\r
4762 /* Matrix describing castling maneuvers */
\r
4763 /* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */
\r
4764 static int castling_matrix[4][5] = {
\r
4765 { 0, 0, 4, 3, 2 }, /* 0-0-0, white */
\r
4766 { 0, 7, 4, 5, 6 }, /* 0-0, white */
\r
4767 { 7, 0, 4, 3, 2 }, /* 0-0-0, black */
\r
4768 { 7, 7, 4, 5, 6 } /* 0-0, black */
\r
4771 /* Checks whether castling occurred. If it did, *rrow and *rcol
\r
4772 are set to the destination (row,col) of the rook that moved.
\r
4774 Returns 1 if castling occurred, 0 if not.
\r
4776 Note: Only handles a max of 1 castling move, so be sure
\r
4777 to call too_many_diffs() first.
\r
4779 static int check_castle_draw(newb, oldb, rrow, rcol)
\r
4786 /* For each type of castling... */
\r
4787 for (i=0; i<4; ++i) {
\r
4788 r = castling_matrix[i];
\r
4790 /* Check the 4 squares involved in the castling move */
\r
4792 for (j=1; j<=4; ++j) {
\r
4793 if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) {
\r
4800 /* All 4 changed, so it must be a castling move */
\r
4809 static int damage[BOARD_SIZE][BOARD_SIZE];
\r
4812 * event handler for redrawing the board
\r
4814 void XDrawPosition(w, repaint, board)
\r
4816 /*Boolean*/int repaint;
\r
4819 int i, j, do_flash;
\r
4820 static int lastFlipView = 0;
\r
4821 static int lastBoardValid = 0;
\r
4822 static Board lastBoard;
\r
4826 if (board == NULL) {
\r
4827 if (!lastBoardValid) return;
\r
4828 board = lastBoard;
\r
4830 if (!lastBoardValid || lastFlipView != flipView) {
\r
4831 XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
\r
4832 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
\r
4837 * It would be simpler to clear the window with XClearWindow()
\r
4838 * but this causes a very distracting flicker.
\r
4841 if (!repaint && lastBoardValid && lastFlipView == flipView) {
\r
4843 /* If too much changes (begin observing new game, etc.), don't
\r
4845 do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
\r
4847 /* Special check for castling so we don't flash both the king
\r
4848 and the rook (just flash the king). */
\r
4850 if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
\r
4851 /* Draw rook with NO flashing. King will be drawn flashing later */
\r
4852 DrawSquare(rrow, rcol, board[rrow][rcol], 0);
\r
4853 lastBoard[rrow][rcol] = board[rrow][rcol];
\r
4857 /* First pass -- Draw (newly) empty squares and repair damage.
\r
4858 This prevents you from having a piece show up twice while it
\r
4859 is flashing on its new square */
\r
4860 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4861 for (j = 0; j < BOARD_WIDTH; j++)
\r
4862 if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
\r
4863 || damage[i][j]) {
\r
4864 DrawSquare(i, j, board[i][j], 0);
\r
4865 damage[i][j] = False;
\r
4868 /* Second pass -- Draw piece(s) in new position and flash them */
\r
4869 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4870 for (j = 0; j < BOARD_WIDTH; j++)
\r
4871 if (board[i][j] != lastBoard[i][j]) {
\r
4872 DrawSquare(i, j, board[i][j], do_flash);
\r
4876 XDrawSegments(xDisplay, xBoardWindow, lineGC,
\r
4877 gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
\r
4879 for (i = 0; i < BOARD_HEIGHT; i++)
\r
4880 for (j = 0; j < BOARD_WIDTH; j++) {
\r
4881 DrawSquare(i, j, board[i][j], 0);
\r
4882 damage[i][j] = False;
\r
4886 CopyBoard(lastBoard, board);
\r
4887 lastBoardValid = 1;
\r
4888 lastFlipView = flipView;
\r
4890 /* Draw highlights */
\r
4891 if (pm1X >= 0 && pm1Y >= 0) {
\r
4892 drawHighlight(pm1X, pm1Y, prelineGC);
\r
4894 if (pm2X >= 0 && pm2Y >= 0) {
\r
4895 drawHighlight(pm2X, pm2Y, prelineGC);
\r
4897 if (hi1X >= 0 && hi1Y >= 0) {
\r
4898 drawHighlight(hi1X, hi1Y, highlineGC);
\r
4900 if (hi2X >= 0 && hi2Y >= 0) {
\r
4901 drawHighlight(hi2X, hi2Y, highlineGC);
\r
4904 /* If piece being dragged around board, must redraw that too */
\r
4907 XSync(xDisplay, False);
\r
4912 * event handler for redrawing the board
\r
4914 void DrawPositionProc(w, event, prms, nprms)
\r
4920 XDrawPosition(w, True, NULL);
\r
4925 * event handler for parsing user moves
\r
4927 // [HGM] This routine will need quite some reworking. Although the backend still supports the old
\r
4928 // way of doing things, by calling UserMoveEvent() to test the legality of the move and then perform
\r
4929 // it at the end, and doing all kind of preliminary tests here (e.g. to weed out self-captures), it
\r
4930 // should be made to use the new way, of calling UserMoveTest early to determine the legality of the
\r
4931 // move, (which will weed out the illegal selfcaptures and moves into the holdings, and flag promotions),
\r
4932 // and at the end FinishMove() to perform the move after optional promotion popups.
\r
4933 // For now I patched it to allow self-capture with King, and suppress clicks between board and holdings.
\r
4934 void HandleUserMove(w, event, prms, nprms)
\r
4941 Boolean saveAnimate;
\r
4942 static int second = 0;
\r
4944 if (w != boardWidget || errorExitStatus != -1) return;
\r
4946 if (event->type == ButtonPress) ErrorPopDown();
\r
4948 if (promotionUp) {
\r
4949 if (event->type == ButtonPress) {
\r
4950 XtPopdown(promotionShell);
\r
4951 XtDestroyWidget(promotionShell);
\r
4952 promotionUp = False;
\r
4953 ClearHighlights();
\r
4954 fromX = fromY = -1;
\r
4960 x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
\r
4961 y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
\r
4962 if (!flipView && y >= 0) {
\r
4963 y = BOARD_HEIGHT - 1 - y;
\r
4965 if (flipView && x >= 0) {
\r
4966 x = BOARD_WIDTH - 1 - x;
\r
4969 /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
\r
4970 if(event->type == ButtonPress
\r
4971 && ( x == BOARD_LEFT-1 || x == BOARD_RGHT
\r
4972 || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize
\r
4973 || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) )
\r
4976 if (fromX == -1) {
\r
4977 if (event->type == ButtonPress) {
\r
4978 /* First square */
\r
4979 if (OKToStartUserMove(x, y)) {
\r
4983 DragPieceBegin(event->xbutton.x, event->xbutton.y);
\r
4984 if (appData.highlightDragging) {
\r
4985 SetHighlights(x, y, -1, -1);
\r
4993 if (event->type == ButtonPress && gameMode != EditPosition &&
\r
4994 x >= 0 && y >= 0) {
\r
4995 ChessSquare fromP;
\r
4998 /* Check if clicking again on the same color piece */
\r
4999 fromP = boards[currentMove][fromY][fromX];
\r
5000 toP = boards[currentMove][y][x];
\r
5001 if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.
\r
5002 WhitePawn <= toP && toP <= WhiteKing) || // For now I made it less critical by exempting King
\r
5003 (BlackPawn <= fromP && fromP < BlackKing && // moves, to not interfere with FRC castlings.
\r
5004 BlackPawn <= toP && toP <= BlackKing)) {
\r
5005 /* Clicked again on same color piece -- changed his mind */
\r
5006 second = (x == fromX && y == fromY);
\r
5007 if (appData.highlightDragging) {
\r
5008 SetHighlights(x, y, -1, -1);
\r
5010 ClearHighlights();
\r
5012 if (OKToStartUserMove(x, y)) {
\r
5015 DragPieceBegin(event->xbutton.x, event->xbutton.y);
\r
5021 if (event->type == ButtonRelease && x == fromX && y == fromY) {
\r
5022 DragPieceEnd(event->xbutton.x, event->xbutton.y);
\r
5023 if (appData.animateDragging) {
\r
5024 /* Undo animation damage if any */
\r
5025 DrawPosition(FALSE, NULL);
\r
5028 /* Second up/down in same square; just abort move */
\r
5030 fromX = fromY = -1;
\r
5031 ClearHighlights();
\r
5033 ClearPremoveHighlights();
\r
5035 /* First upclick in same square; start click-click mode */
\r
5036 SetHighlights(x, y, -1, -1);
\r
5041 /* Completed move */
\r
5044 saveAnimate = appData.animate;
\r
5045 if (event->type == ButtonPress) {
\r
5046 /* Finish clickclick move */
\r
5047 if (appData.animate || appData.highlightLastMove) {
\r
5048 SetHighlights(fromX, fromY, toX, toY);
\r
5050 ClearHighlights();
\r
5053 /* Finish drag move */
\r
5054 if (appData.highlightLastMove) {
\r
5055 SetHighlights(fromX, fromY, toX, toY);
\r
5057 ClearHighlights();
\r
5059 DragPieceEnd(event->xbutton.x, event->xbutton.y);
\r
5060 /* Don't animate move and drag both */
\r
5061 appData.animate = FALSE;
\r
5063 if (IsPromotion(fromX, fromY, toX, toY)) {
\r
5064 if (appData.alwaysPromoteToQueen) {
\r
5065 UserMoveEvent(fromX, fromY, toX, toY, 'q');
\r
5066 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5067 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5068 fromX = fromY = -1;
\r
5070 SetHighlights(fromX, fromY, toX, toY);
\r
5074 UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
\r
5075 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5076 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5077 fromX = fromY = -1;
\r
5079 appData.animate = saveAnimate;
\r
5080 if (appData.animate || appData.animateDragging) {
\r
5081 /* Undo animation damage if needed */
\r
5082 DrawPosition(FALSE, NULL);
\r
5086 void AnimateUserMove (Widget w, XEvent * event,
\r
5087 String * params, Cardinal * nParams)
\r
5089 DragPieceMove(event->xmotion.x, event->xmotion.y);
\r
5092 Widget CommentCreate(name, text, mutable, callback, lines)
\r
5093 char *name, *text;
\r
5094 int /*Boolean*/ mutable;
\r
5095 XtCallbackProc callback;
\r
5099 Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
\r
5100 Dimension bw_width;
\r
5104 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5105 XtGetValues(boardWidget, args, j);
\r
5108 XtSetArg(args[j], XtNresizable, True); j++;
\r
5111 XtCreatePopupShell(name, topLevelShellWidgetClass,
\r
5112 shellWidget, args, j);
\r
5115 XtCreatePopupShell(name, transientShellWidgetClass,
\r
5116 shellWidget, args, j);
\r
5119 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
\r
5120 layoutArgs, XtNumber(layoutArgs));
\r
5122 XtCreateManagedWidget("form", formWidgetClass, layout,
\r
5123 formArgs, XtNumber(formArgs));
\r
5127 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
\r
5128 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
\r
5130 XtSetArg(args[j], XtNstring, text); j++;
\r
5131 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
5132 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5133 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5134 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
5135 XtSetArg(args[j], XtNresizable, True); j++;
\r
5136 XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/
\r
5138 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
\r
5140 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
\r
5141 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
\r
5143 XtSetArg(args[j], XtNautoFill, True); j++;
\r
5144 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
\r
5146 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
\r
5150 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5151 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5152 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5153 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5154 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5156 XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j);
\r
5157 XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
\r
5160 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5161 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
\r
5162 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5163 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5164 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5165 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5167 XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
\r
5168 XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
\r
5171 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5172 XtSetArg(args[j], XtNfromHoriz, b_cancel); j++;
\r
5173 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5174 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5175 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5176 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5178 XtCreateManagedWidget(_("clear"), commandWidgetClass, form, args, j);
\r
5179 XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
\r
5182 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5183 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5184 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5185 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5186 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5188 XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j);
\r
5189 XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
\r
5192 XtSetArg(args[j], XtNfromVert, edit); j++;
\r
5193 XtSetArg(args[j], XtNfromHoriz, b_close); j++;
\r
5194 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
5195 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5196 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5197 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
5199 XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j);
\r
5200 XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
\r
5203 XtRealizeWidget(shell);
\r
5205 if (commentX == -1) {
\r
5208 Dimension pw_height;
\r
5209 Dimension ew_height;
\r
5212 XtSetArg(args[j], XtNheight, &ew_height); j++;
\r
5213 XtGetValues(edit, args, j);
\r
5216 XtSetArg(args[j], XtNheight, &pw_height); j++;
\r
5217 XtGetValues(shell, args, j);
\r
5218 commentH = pw_height + (lines - 1) * ew_height;
\r
5219 commentW = bw_width - 16;
\r
5221 XSync(xDisplay, False);
\r
5223 /* This code seems to tickle an X bug if it is executed too soon
\r
5224 after xboard starts up. The coordinates get transformed as if
\r
5225 the main window was positioned at (0, 0).
\r
5227 XtTranslateCoords(shellWidget,
\r
5228 (bw_width - commentW) / 2, 0 - commentH / 2,
\r
5229 &commentX, &commentY);
\r
5231 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
\r
5232 RootWindowOfScreen(XtScreen(shellWidget)),
\r
5233 (bw_width - commentW) / 2, 0 - commentH / 2,
\r
5237 #endif /*!NOTDEF*/
\r
5238 if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/
\r
5241 XtSetArg(args[j], XtNheight, commentH); j++;
\r
5242 XtSetArg(args[j], XtNwidth, commentW); j++;
\r
5243 XtSetArg(args[j], XtNx, commentX); j++;
\r
5244 XtSetArg(args[j], XtNy, commentY); j++;
\r
5245 XtSetValues(shell, args, j);
\r
5246 XtSetKeyboardFocus(shell, edit);
\r
5251 /* Used for analysis window and ICS input window */
\r
5252 Widget MiscCreate(name, text, mutable, callback, lines)
\r
5253 char *name, *text;
\r
5254 int /*Boolean*/ mutable;
\r
5255 XtCallbackProc callback;
\r
5259 Widget shell, layout, form, edit;
\r
5261 Dimension bw_width, pw_height, ew_height, w, h;
\r
5267 XtSetArg(args[j], XtNresizable, True); j++;
\r
5270 XtCreatePopupShell(name, topLevelShellWidgetClass,
\r
5271 shellWidget, args, j);
\r
5274 XtCreatePopupShell(name, transientShellWidgetClass,
\r
5275 shellWidget, args, j);
\r
5278 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
\r
5279 layoutArgs, XtNumber(layoutArgs));
\r
5281 XtCreateManagedWidget("form", formWidgetClass, layout,
\r
5282 formArgs, XtNumber(formArgs));
\r
5286 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
\r
5287 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
\r
5289 XtSetArg(args[j], XtNstring, text); j++;
\r
5290 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
5291 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
5292 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
5293 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
5294 XtSetArg(args[j], XtNresizable, True); j++;
\r
5296 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
\r
5298 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
\r
5299 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
\r
5301 XtSetArg(args[j], XtNautoFill, True); j++;
\r
5302 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
\r
5304 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
\r
5306 XtRealizeWidget(shell);
\r
5309 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5310 XtGetValues(boardWidget, args, j);
\r
5313 XtSetArg(args[j], XtNheight, &ew_height); j++;
\r
5314 XtGetValues(edit, args, j);
\r
5317 XtSetArg(args[j], XtNheight, &pw_height); j++;
\r
5318 XtGetValues(shell, args, j);
\r
5319 h = pw_height + (lines - 1) * ew_height;
\r
5320 w = bw_width - 16;
\r
5322 XSync(xDisplay, False);
\r
5324 /* This code seems to tickle an X bug if it is executed too soon
\r
5325 after xboard starts up. The coordinates get transformed as if
\r
5326 the main window was positioned at (0, 0).
\r
5328 XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);
\r
5330 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
\r
5331 RootWindowOfScreen(XtScreen(shellWidget)),
\r
5332 (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
\r
5333 #endif /*!NOTDEF*/
\r
5336 if (y < 0) y = 0; /*avoid positioning top offscreen*/
\r
5339 XtSetArg(args[j], XtNheight, h); j++;
\r
5340 XtSetArg(args[j], XtNwidth, w); j++;
\r
5341 XtSetArg(args[j], XtNx, x); j++;
\r
5342 XtSetArg(args[j], XtNy, y); j++;
\r
5343 XtSetValues(shell, args, j);
\r
5349 static int savedIndex; /* gross that this is global */
\r
5351 void EditCommentPopUp(index, title, text)
\r
5353 char *title, *text;
\r
5359 savedIndex = index;
\r
5360 if (text == NULL) text = "";
\r
5362 if (editShell == NULL) {
\r
5364 CommentCreate(title, text, True, EditCommentCallback, 4);
\r
5365 XtRealizeWidget(editShell);
\r
5366 CatchDeleteWindow(editShell, "EditCommentPopDown");
\r
5368 edit = XtNameToWidget(editShell, "*form.text");
\r
5370 XtSetArg(args[j], XtNstring, text); j++;
\r
5371 XtSetValues(edit, args, j);
\r
5373 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5374 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5375 XtSetValues(editShell, args, j);
\r
5378 XtPopup(editShell, XtGrabNone);
\r
5382 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
5383 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
\r
5387 void EditCommentCallback(w, client_data, call_data)
\r
5389 XtPointer client_data, call_data;
\r
5397 XtSetArg(args[j], XtNlabel, &name); j++;
\r
5398 XtGetValues(w, args, j);
\r
5400 if (strcmp(name, _("ok")) == 0) {
\r
5401 edit = XtNameToWidget(editShell, "*form.text");
\r
5403 XtSetArg(args[j], XtNstring, &val); j++;
\r
5404 XtGetValues(edit, args, j);
\r
5405 ReplaceComment(savedIndex, val);
\r
5406 EditCommentPopDown();
\r
5407 } else if (strcmp(name, _("cancel")) == 0) {
\r
5408 EditCommentPopDown();
\r
5409 } else if (strcmp(name, _("clear")) == 0) {
\r
5410 edit = XtNameToWidget(editShell, "*form.text");
\r
5411 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
\r
5412 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
\r
5416 void EditCommentPopDown()
\r
5421 if (!editUp) return;
\r
5423 XtSetArg(args[j], XtNx, &commentX); j++;
\r
5424 XtSetArg(args[j], XtNy, &commentY); j++;
\r
5425 XtSetArg(args[j], XtNheight, &commentH); j++;
\r
5426 XtSetArg(args[j], XtNwidth, &commentW); j++;
\r
5427 XtGetValues(editShell, args, j);
\r
5428 XtPopdown(editShell);
\r
5431 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
5432 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
\r
5436 void ICSInputBoxPopUp()
\r
5441 char *title = _("ICS Input");
\r
5442 XtTranslations tr;
\r
5444 if (ICSInputShell == NULL) {
\r
5445 ICSInputShell = MiscCreate(title, "", True, NULL, 1);
\r
5446 tr = XtParseTranslationTable(ICSInputTranslations);
\r
5447 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5448 XtOverrideTranslations(edit, tr);
\r
5449 XtRealizeWidget(ICSInputShell);
\r
5450 CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
\r
5453 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5455 XtSetArg(args[j], XtNstring, ""); j++;
\r
5456 XtSetValues(edit, args, j);
\r
5458 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5459 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5460 XtSetValues(ICSInputShell, args, j);
\r
5463 XtPopup(ICSInputShell, XtGrabNone);
\r
5464 XtSetKeyboardFocus(ICSInputShell, edit);
\r
5466 ICSInputBoxUp = True;
\r
5468 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
5469 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
\r
5473 void ICSInputSendText()
\r
5480 edit = XtNameToWidget(ICSInputShell, "*form.text");
\r
5482 XtSetArg(args[j], XtNstring, &val); j++;
\r
5483 XtGetValues(edit, args, j);
\r
5484 SendMultiLineToICS(val);
\r
5485 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
\r
5486 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
\r
5489 void ICSInputBoxPopDown()
\r
5494 if (!ICSInputBoxUp) return;
\r
5496 XtPopdown(ICSInputShell);
\r
5497 ICSInputBoxUp = False;
\r
5499 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
5500 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
\r
5504 void CommentPopUp(title, text)
\r
5505 char *title, *text;
\r
5511 if (commentShell == NULL) {
\r
5513 CommentCreate(title, text, False, CommentCallback, 4);
\r
5514 XtRealizeWidget(commentShell);
\r
5515 CatchDeleteWindow(commentShell, "CommentPopDown");
\r
5517 edit = XtNameToWidget(commentShell, "*form.text");
\r
5519 XtSetArg(args[j], XtNstring, text); j++;
\r
5520 XtSetValues(edit, args, j);
\r
5522 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5523 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5524 XtSetValues(commentShell, args, j);
\r
5527 XtPopup(commentShell, XtGrabNone);
\r
5528 XSync(xDisplay, False);
\r
5533 void AnalysisPopUp(title, text)
\r
5534 char *title, *text;
\r
5540 if (analysisShell == NULL) {
\r
5541 analysisShell = MiscCreate(title, text, False, NULL, 4);
\r
5542 XtRealizeWidget(analysisShell);
\r
5543 CatchDeleteWindow(analysisShell, "AnalysisPopDown");
\r
5546 edit = XtNameToWidget(analysisShell, "*form.text");
\r
5548 XtSetArg(args[j], XtNstring, text); j++;
\r
5549 XtSetValues(edit, args, j);
\r
5551 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
\r
5552 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
\r
5553 XtSetValues(analysisShell, args, j);
\r
5556 if (!analysisUp) {
\r
5557 XtPopup(analysisShell, XtGrabNone);
\r
5559 XSync(xDisplay, False);
\r
5561 analysisUp = True;
\r
5564 void CommentCallback(w, client_data, call_data)
\r
5566 XtPointer client_data, call_data;
\r
5573 XtSetArg(args[j], XtNlabel, &name); j++;
\r
5574 XtGetValues(w, args, j);
\r
5576 if (strcmp(name, _("close")) == 0) {
\r
5578 } else if (strcmp(name, _("edit")) == 0) {
\r
5580 EditCommentEvent();
\r
5585 void CommentPopDown()
\r
5590 if (!commentUp) return;
\r
5592 XtSetArg(args[j], XtNx, &commentX); j++;
\r
5593 XtSetArg(args[j], XtNy, &commentY); j++;
\r
5594 XtSetArg(args[j], XtNwidth, &commentW); j++;
\r
5595 XtSetArg(args[j], XtNheight, &commentH); j++;
\r
5596 XtGetValues(commentShell, args, j);
\r
5597 XtPopdown(commentShell);
\r
5598 XSync(xDisplay, False);
\r
5599 commentUp = False;
\r
5602 void AnalysisPopDown()
\r
5604 if (!analysisUp) return;
\r
5605 XtPopdown(analysisShell);
\r
5606 XSync(xDisplay, False);
\r
5607 analysisUp = False;
\r
5608 if (appData.icsEngineAnalyze) ExitAnalyzeMode(); /* [DM] icsEngineAnalyze */
\r
5612 void FileNamePopUp(label, def, proc, openMode)
\r
5619 Widget popup, layout, dialog, edit;
\r
5620 Window root, child;
\r
5623 unsigned int mask;
\r
5625 fileProc = proc; /* I can't see a way not */
\r
5626 fileOpenMode = openMode; /* to use globals here */
\r
5629 XtSetArg(args[i], XtNresizable, True); i++;
\r
5630 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
\r
5631 XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++;
\r
5632 fileNameShell = popup =
\r
5633 XtCreatePopupShell("File name prompt", transientShellWidgetClass,
\r
5634 shellWidget, args, i);
\r
5637 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
\r
5638 layoutArgs, XtNumber(layoutArgs));
\r
5641 XtSetArg(args[i], XtNlabel, label); i++;
\r
5642 XtSetArg(args[i], XtNvalue, def); i++;
\r
5643 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
5644 dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
\r
5647 XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog);
\r
5648 XawDialogAddButton(dialog, _("cancel"), FileNameCallback,
\r
5649 (XtPointer) dialog);
\r
5651 XtRealizeWidget(popup);
\r
5652 CatchDeleteWindow(popup, "FileNamePopDown");
\r
5654 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
\r
5655 &x, &y, &win_x, &win_y, &mask);
\r
5657 XtSetArg(args[0], XtNx, x - 10);
\r
5658 XtSetArg(args[1], XtNy, y - 30);
\r
5659 XtSetValues(popup, args, 2);
\r
5661 XtPopup(popup, XtGrabExclusive);
\r
5662 filenameUp = True;
\r
5664 edit = XtNameToWidget(dialog, "*value");
\r
5665 XtSetKeyboardFocus(popup, edit);
\r
5668 void FileNamePopDown()
\r
5670 if (!filenameUp) return;
\r
5671 XtPopdown(fileNameShell);
\r
5672 XtDestroyWidget(fileNameShell);
\r
5673 filenameUp = False;
\r
5677 void FileNameCallback(w, client_data, call_data)
\r
5679 XtPointer client_data, call_data;
\r
5684 XtSetArg(args[0], XtNlabel, &name);
\r
5685 XtGetValues(w, args, 1);
\r
5687 if (strcmp(name, _("cancel")) == 0) {
\r
5688 FileNamePopDown();
\r
5692 FileNameAction(w, NULL, NULL, NULL);
\r
5695 void FileNameAction(w, event, prms, nprms)
\r
5701 char buf[MSG_SIZ];
\r
5704 char *p, *fullname;
\r
5707 name = XawDialogGetValueString(w = XtParent(w));
\r
5709 if ((name != NULL) && (*name != NULLCHAR)) {
\r
5710 strcpy(buf, name);
\r
5711 XtPopdown(w = XtParent(XtParent(w)));
\r
5712 XtDestroyWidget(w);
\r
5713 filenameUp = False;
\r
5715 p = strrchr(buf, ' ');
\r
5722 fullname = ExpandPathName(buf);
\r
5724 ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
\r
5727 f = fopen(fullname, fileOpenMode);
\r
5729 DisplayError(_("Failed to open file"), errno);
\r
5731 (void) (*fileProc)(f, index, buf);
\r
5738 XtPopdown(w = XtParent(XtParent(w)));
\r
5739 XtDestroyWidget(w);
\r
5740 filenameUp = False;
\r
5744 void PromotionPopUp()
\r
5747 Widget dialog, layout;
\r
5749 Dimension bw_width, pw_width;
\r
5753 XtSetArg(args[j], XtNwidth, &bw_width); j++;
\r
5754 XtGetValues(boardWidget, args, j);
\r
5757 XtSetArg(args[j], XtNresizable, True); j++;
\r
5758 XtSetArg(args[j], XtNtitle, XtNewString(_("Promotion"))); j++;
\r
5760 XtCreatePopupShell("Promotion", transientShellWidgetClass,
\r
5761 shellWidget, args, j);
\r
5763 XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
\r
5764 layoutArgs, XtNumber(layoutArgs));
\r
5767 XtSetArg(args[j], XtNlabel, _("Promote pawn to what?")); j++;
\r
5768 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
5769 dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
\r
5772 XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
\r
5773 (XtPointer) dialog);
\r
5774 XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
\r
5775 (XtPointer) dialog);
\r
5776 XawDialogAddButton(dialog, _("Bishop"), PromotionCallback,
\r
5777 (XtPointer) dialog);
\r
5778 XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
\r
5779 (XtPointer) dialog);
\r
5780 if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
\r
5781 gameInfo.variant == VariantGiveaway) {
\r
5782 XawDialogAddButton(dialog, _("King"), PromotionCallback,
\r
5783 (XtPointer) dialog);
\r
5785 XawDialogAddButton(dialog, _("cancel"), PromotionCallback,
\r
5786 (XtPointer) dialog);
\r
5788 XtRealizeWidget(promotionShell);
\r
5789 CatchDeleteWindow(promotionShell, "PromotionPopDown");
\r
5792 XtSetArg(args[j], XtNwidth, &pw_width); j++;
\r
5793 XtGetValues(promotionShell, args, j);
\r
5795 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
\r
5796 lineGap + squareSize/3 +
\r
5797 ((toY == BOARD_HEIGHT-1) ^ (flipView) ?
\r
5798 0 : 6*(squareSize + lineGap)), &x, &y);
\r
5801 XtSetArg(args[j], XtNx, x); j++;
\r
5802 XtSetArg(args[j], XtNy, y); j++;
\r
5803 XtSetValues(promotionShell, args, j);
\r
5805 XtPopup(promotionShell, XtGrabNone);
\r
5807 promotionUp = True;
\r
5810 void PromotionPopDown()
\r
5812 if (!promotionUp) return;
\r
5813 XtPopdown(promotionShell);
\r
5814 XtDestroyWidget(promotionShell);
\r
5815 promotionUp = False;
\r
5818 void PromotionCallback(w, client_data, call_data)
\r
5820 XtPointer client_data, call_data;
\r
5826 XtSetArg(args[0], XtNlabel, &name);
\r
5827 XtGetValues(w, args, 1);
\r
5829 PromotionPopDown();
\r
5831 if (fromX == -1) return;
\r
5833 if (strcmp(name, _("cancel")) == 0) {
\r
5834 fromX = fromY = -1;
\r
5835 ClearHighlights();
\r
5837 } else if (strcmp(name, _("Knight")) == 0) {
\r
5840 promoChar = ToLower(name[0]);
\r
5843 UserMoveEvent(fromX, fromY, toX, toY, promoChar);
\r
5845 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
\r
5846 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
\r
5847 fromX = fromY = -1;
\r
5851 void ErrorCallback(w, client_data, call_data)
\r
5853 XtPointer client_data, call_data;
\r
5856 XtPopdown(w = XtParent(XtParent(XtParent(w))));
\r
5857 XtDestroyWidget(w);
\r
5858 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
\r
5862 void ErrorPopDown()
\r
5864 if (!errorUp) return;
\r
5866 XtPopdown(errorShell);
\r
5867 XtDestroyWidget(errorShell);
\r
5868 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
\r
5871 void ErrorPopUp(title, label, modal)
\r
5872 char *title, *label;
\r
5876 Widget dialog, layout;
\r
5880 Dimension bw_width, pw_width;
\r
5881 Dimension pw_height;
\r
5885 XtSetArg(args[i], XtNresizable, True); i++;
\r
5886 XtSetArg(args[i], XtNtitle, title); i++;
\r
5888 XtCreatePopupShell("errorpopup", transientShellWidgetClass,
\r
5889 shellWidget, args, i);
\r
5891 XtCreateManagedWidget(layoutName, formWidgetClass, errorShell,
\r
5892 layoutArgs, XtNumber(layoutArgs));
\r
5895 XtSetArg(args[i], XtNlabel, label); i++;
\r
5896 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
5897 dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
\r
5900 XawDialogAddButton(dialog, _("ok"), ErrorCallback, (XtPointer) dialog);
\r
5902 XtRealizeWidget(errorShell);
\r
5903 CatchDeleteWindow(errorShell, "ErrorPopDown");
\r
5906 XtSetArg(args[i], XtNwidth, &bw_width); i++;
\r
5907 XtGetValues(boardWidget, args, i);
\r
5909 XtSetArg(args[i], XtNwidth, &pw_width); i++;
\r
5910 XtSetArg(args[i], XtNheight, &pw_height); i++;
\r
5911 XtGetValues(errorShell, args, i);
\r
5914 /* This code seems to tickle an X bug if it is executed too soon
\r
5915 after xboard starts up. The coordinates get transformed as if
\r
5916 the main window was positioned at (0, 0).
\r
5918 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
\r
5919 0 - pw_height + squareSize / 3, &x, &y);
\r
5921 XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
\r
5922 RootWindowOfScreen(XtScreen(boardWidget)),
\r
5923 (bw_width - pw_width) / 2,
\r
5924 0 - pw_height + squareSize / 3, &xx, &yy, &junk);
\r
5928 if (y < 0) y = 0; /*avoid positioning top offscreen*/
\r
5931 XtSetArg(args[i], XtNx, x); i++;
\r
5932 XtSetArg(args[i], XtNy, y); i++;
\r
5933 XtSetValues(errorShell, args, i);
\r
5936 XtPopup(errorShell, modal ? XtGrabExclusive : XtGrabNone);
\r
5939 /* Disable all user input other than deleting the window */
\r
5940 static int frozen = 0;
\r
5943 if (frozen) return;
\r
5944 /* Grab by a widget that doesn't accept input */
\r
5945 XtAddGrab(messageWidget, TRUE, FALSE);
\r
5949 /* Undo a FreezeUI */
\r
5952 if (!frozen) return;
\r
5953 XtRemoveGrab(messageWidget);
\r
5957 char *ModeToWidgetName(mode)
\r
5961 case BeginningOfGame:
\r
5962 if (appData.icsActive)
\r
5963 return "menuMode.ICS Client";
\r
5964 else if (appData.noChessProgram ||
\r
5965 *appData.cmailGameName != NULLCHAR)
\r
5966 return "menuMode.Edit Game";
\r
5968 return "menuMode.Machine Black";
\r
5969 case MachinePlaysBlack:
\r
5970 return "menuMode.Machine Black";
\r
5971 case MachinePlaysWhite:
\r
5972 return "menuMode.Machine White";
\r
5974 return "menuMode.Analysis Mode";
\r
5976 return "menuMode.Analyze File";
\r
5977 case TwoMachinesPlay:
\r
5978 return "menuMode.Two Machines";
\r
5980 return "menuMode.Edit Game";
\r
5981 case PlayFromGameFile:
\r
5982 return "menuFile.Load Game";
\r
5983 case EditPosition:
\r
5984 return "menuMode.Edit Position";
\r
5986 return "menuMode.Training";
\r
5987 case IcsPlayingWhite:
\r
5988 case IcsPlayingBlack:
\r
5989 case IcsObserving:
\r
5991 case IcsExamining:
\r
5992 return "menuMode.ICS Client";
\r
5999 void ModeHighlight()
\r
6002 static int oldPausing = FALSE;
\r
6003 static GameMode oldmode = (GameMode) -1;
\r
6006 if (!boardWidget || !XtIsRealized(boardWidget)) return;
\r
6008 if (pausing != oldPausing) {
\r
6009 oldPausing = pausing;
\r
6011 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6013 XtSetArg(args[0], XtNleftBitmap, None);
\r
6015 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),
\r
6018 if (appData.showButtonBar) {
\r
6021 XtSetArg(args[0], XtNbackground, buttonForegroundPixel);
\r
6022 XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);
\r
6024 XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);
\r
6025 XtSetArg(args[1], XtNforeground, buttonForegroundPixel);
\r
6028 /* Always toggle, don't set. Previous code messes up when
\r
6029 invoked while the button is pressed, as releasing it
\r
6030 toggles the state again. */
\r
6032 Pixel oldbg, oldfg;
\r
6033 XtSetArg(args[0], XtNbackground, &oldbg);
\r
6034 XtSetArg(args[1], XtNforeground, &oldfg);
\r
6035 XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON),
\r
6037 XtSetArg(args[0], XtNbackground, oldfg);
\r
6038 XtSetArg(args[1], XtNforeground, oldbg);
\r
6041 XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
\r
6045 wname = ModeToWidgetName(oldmode);
\r
6046 if (wname != NULL) {
\r
6047 XtSetArg(args[0], XtNleftBitmap, None);
\r
6048 XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
\r
6050 wname = ModeToWidgetName(gameMode);
\r
6051 if (wname != NULL) {
\r
6052 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6053 XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
\r
6055 oldmode = gameMode;
\r
6057 /* Maybe all the enables should be handled here, not just this one */
\r
6058 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"),
\r
6059 gameMode == Training || gameMode == PlayFromGameFile);
\r
6064 * Button/menu procedures
\r
6066 void ResetProc(w, event, prms, nprms)
\r
6073 AnalysisPopDown();
\r
6076 int LoadGamePopUp(f, gameNumber, title)
\r
6081 cmailMsgLoaded = FALSE;
\r
6082 if (gameNumber == 0) {
\r
6083 int error = GameListBuild(f);
\r
6085 DisplayError(_("Cannot build game list"), error);
\r
6086 } else if (!ListEmpty(&gameList) &&
\r
6087 ((ListGame *) gameList.tailPred)->number > 1) {
\r
6088 GameListPopUp(f, title);
\r
6091 GameListDestroy();
\r
6094 return LoadGame(f, gameNumber, title, FALSE);
\r
6097 void LoadGameProc(w, event, prms, nprms)
\r
6103 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
\r
6104 Reset(FALSE, TRUE);
\r
6106 FileNamePopUp(_("Load game file name?"), "", LoadGamePopUp, "rb");
\r
6109 void LoadNextGameProc(w, event, prms, nprms)
\r
6118 void LoadPrevGameProc(w, event, prms, nprms)
\r
6127 void ReloadGameProc(w, event, prms, nprms)
\r
6136 void LoadNextPositionProc(w, event, prms, nprms)
\r
6142 ReloadPosition(1);
\r
6145 void LoadPrevPositionProc(w, event, prms, nprms)
\r
6151 ReloadPosition(-1);
\r
6154 void ReloadPositionProc(w, event, prms, nprms)
\r
6160 ReloadPosition(0);
\r
6163 void LoadPositionProc(w, event, prms, nprms)
\r
6169 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
\r
6170 Reset(FALSE, TRUE);
\r
6172 FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
\r
6175 void SaveGameProc(w, event, prms, nprms)
\r
6181 FileNamePopUp(_("Save game file name?"),
\r
6182 DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
\r
6186 void SavePositionProc(w, event, prms, nprms)
\r
6192 FileNamePopUp(_("Save position file name?"),
\r
6193 DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
\r
6194 SavePosition, "a");
\r
6197 void ReloadCmailMsgProc(w, event, prms, nprms)
\r
6203 ReloadCmailMsgEvent(FALSE);
\r
6206 void MailMoveProc(w, event, prms, nprms)
\r
6215 /* this variable is shared between CopyPositionProc and SendPositionSelection */
\r
6216 static char *selected_fen_position=NULL;
\r
6219 SendPositionSelection(Widget w, Atom *selection, Atom *target,
\r
6220 Atom *type_return, XtPointer *value_return,
\r
6221 unsigned long *length_return, int *format_return)
\r
6223 char *selection_tmp;
\r
6225 if (!selected_fen_position) return False; /* should never happen */
\r
6226 if (*target == XA_STRING){
\r
6227 /* note: since no XtSelectionDoneProc was registered, Xt will
\r
6228 * automatically call XtFree on the value returned. So have to
\r
6229 * make a copy of it allocated with XtMalloc */
\r
6230 selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
\r
6231 strcpy(selection_tmp, selected_fen_position);
\r
6233 *value_return=selection_tmp;
\r
6234 *length_return=strlen(selection_tmp);
\r
6235 *type_return=XA_STRING;
\r
6236 *format_return = 8; /* bits per byte */
\r
6243 /* note: when called from menu all parameters are NULL, so no clue what the
\r
6244 * Widget which was clicked on was, or what the click event was
\r
6246 void CopyPositionProc(w, event, prms, nprms)
\r
6254 if (selected_fen_position) free(selected_fen_position);
\r
6255 selected_fen_position = (char *)PositionToFEN(currentMove,1);
\r
6256 if (!selected_fen_position) return;
\r
6257 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
\r
6259 SendPositionSelection,
\r
6260 NULL/* lose_ownership_proc */ ,
\r
6261 NULL/* transfer_done_proc */);
\r
6263 free(selected_fen_position);
\r
6264 selected_fen_position=NULL;
\r
6268 /* function called when the data to Paste is ready */
\r
6270 PastePositionCB(Widget w, XtPointer client_data, Atom *selection,
\r
6271 Atom *type, XtPointer value, unsigned long *len, int *format)
\r
6273 char *fenstr=value;
\r
6274 if (value==NULL || *len==0) return; /* nothing had been selected to copy */
\r
6275 fenstr[*len]='\0'; /* normally this string is terminated, but be safe */
\r
6276 EditPositionPasteFEN(fenstr);
\r
6280 /* called when Paste Position button is pressed,
\r
6281 * all parameters will be NULL */
\r
6282 void PastePositionProc(w, event, prms, nprms)
\r
6288 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
\r
6289 /* (XtSelectionCallbackProc) */ PastePositionCB,
\r
6290 NULL, /* client_data passed to PastePositionCB */
\r
6292 /* better to use the time field from the event that triggered the
\r
6293 * call to this function, but that isn't trivial to get
\r
6301 SendGameSelection(Widget w, Atom *selection, Atom *target,
\r
6302 Atom *type_return, XtPointer *value_return,
\r
6303 unsigned long *length_return, int *format_return)
\r
6305 char *selection_tmp;
\r
6307 if (*target == XA_STRING){
\r
6308 FILE* f = fopen(gameCopyFilename, "r");
\r
6311 if (f == NULL) return False;
\r
6315 selection_tmp = XtMalloc(len + 1);
\r
6316 count = fread(selection_tmp, 1, len, f);
\r
6317 if (len != count) {
\r
6318 XtFree(selection_tmp);
\r
6321 selection_tmp[len] = NULLCHAR;
\r
6322 *value_return = selection_tmp;
\r
6323 *length_return = len;
\r
6324 *type_return = XA_STRING;
\r
6325 *format_return = 8; /* bits per byte */
\r
6332 /* note: when called from menu all parameters are NULL, so no clue what the
\r
6333 * Widget which was clicked on was, or what the click event was
\r
6335 void CopyGameProc(w, event, prms, nprms)
\r
6343 ret = SaveGameToFile(gameCopyFilename, FALSE);
\r
6346 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
\r
6348 SendGameSelection,
\r
6349 NULL/* lose_ownership_proc */ ,
\r
6350 NULL/* transfer_done_proc */);
\r
6353 /* function called when the data to Paste is ready */
\r
6355 PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
\r
6356 Atom *type, XtPointer value, unsigned long *len, int *format)
\r
6359 if (value == NULL || *len == 0) {
\r
6360 return; /* nothing had been selected to copy */
\r
6362 f = fopen(gamePasteFilename, "w");
\r
6364 DisplayError(_("Can't open temp file"), errno);
\r
6367 fwrite(value, 1, *len, f);
\r
6370 LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);
\r
6373 /* called when Paste Game button is pressed,
\r
6374 * all parameters will be NULL */
\r
6375 void PasteGameProc(w, event, prms, nprms)
\r
6381 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
\r
6382 /* (XtSelectionCallbackProc) */ PasteGameCB,
\r
6383 NULL, /* client_data passed to PasteGameCB */
\r
6385 /* better to use the time field from the event that triggered the
\r
6386 * call to this function, but that isn't trivial to get
\r
6394 void AutoSaveGame()
\r
6396 SaveGameProc(NULL, NULL, NULL, NULL);
\r
6400 void QuitProc(w, event, prms, nprms)
\r
6409 void PauseProc(w, event, prms, nprms)
\r
6419 void MachineBlackProc(w, event, prms, nprms)
\r
6425 MachineBlackEvent();
\r
6428 void MachineWhiteProc(w, event, prms, nprms)
\r
6434 MachineWhiteEvent();
\r
6437 void AnalyzeModeProc(w, event, prms, nprms)
\r
6443 char buf[MSG_SIZ];
\r
6445 if (!first.analysisSupport) {
\r
6446 sprintf(buf, _("%s does not support analysis"), first.tidy);
\r
6447 DisplayError(buf, 0);
\r
6450 /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */
\r
6451 if (appData.icsActive) {
\r
6452 if (gameMode != IcsObserving) {
\r
6453 sprintf(buf,_("You are not observing a game"));
\r
6454 DisplayError(buf, 0);
\r
6455 /* secure check */
\r
6456 if (appData.icsEngineAnalyze) {
\r
6457 if (appData.debugMode)
\r
6458 fprintf(debugFP, _("Found unexpected active ICS engine analyze \n"));
\r
6459 ExitAnalyzeMode();
\r
6464 /* if enable, use want disable icsEngineAnalyze */
\r
6465 if (appData.icsEngineAnalyze) {
\r
6466 ExitAnalyzeMode();
\r
6470 appData.icsEngineAnalyze = TRUE;
\r
6471 if (appData.debugMode)
\r
6472 fprintf(debugFP, _("ICS engine analyze starting... \n"));
\r
6474 if (!appData.showThinking)
\r
6475 ShowThinkingProc(w,event,prms,nprms);
\r
6477 AnalyzeModeEvent();
\r
6480 void AnalyzeFileProc(w, event, prms, nprms)
\r
6486 if (!first.analysisSupport) {
\r
6487 char buf[MSG_SIZ];
\r
6488 sprintf(buf, _("%s does not support analysis"), first.tidy);
\r
6489 DisplayError(buf, 0);
\r
6492 Reset(FALSE, TRUE);
\r
6494 if (!appData.showThinking)
\r
6495 ShowThinkingProc(w,event,prms,nprms);
\r
6497 AnalyzeFileEvent();
\r
6498 FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
\r
6499 AnalysisPeriodicEvent(1);
\r
6502 void TwoMachinesProc(w, event, prms, nprms)
\r
6508 TwoMachinesEvent();
\r
6511 void IcsClientProc(w, event, prms, nprms)
\r
6520 void EditGameProc(w, event, prms, nprms)
\r
6529 void EditPositionProc(w, event, prms, nprms)
\r
6535 EditPositionEvent();
\r
6538 void TrainingProc(w, event, prms, nprms)
\r
6547 void EditCommentProc(w, event, prms, nprms)
\r
6554 EditCommentPopDown();
\r
6556 EditCommentEvent();
\r
6560 void IcsInputBoxProc(w, event, prms, nprms)
\r
6566 if (ICSInputBoxUp) {
\r
6567 ICSInputBoxPopDown();
\r
6569 ICSInputBoxPopUp();
\r
6573 void AcceptProc(w, event, prms, nprms)
\r
6582 void DeclineProc(w, event, prms, nprms)
\r
6591 void RematchProc(w, event, prms, nprms)
\r
6600 void CallFlagProc(w, event, prms, nprms)
\r
6609 void DrawProc(w, event, prms, nprms)
\r
6618 void AbortProc(w, event, prms, nprms)
\r
6627 void AdjournProc(w, event, prms, nprms)
\r
6636 void ResignProc(w, event, prms, nprms)
\r
6645 void EnterKeyProc(w, event, prms, nprms)
\r
6651 if (ICSInputBoxUp == True)
\r
6652 ICSInputSendText();
\r
6655 void StopObservingProc(w, event, prms, nprms)
\r
6661 StopObservingEvent();
\r
6664 void StopExaminingProc(w, event, prms, nprms)
\r
6670 StopExaminingEvent();
\r
6674 void ForwardProc(w, event, prms, nprms)
\r
6684 void BackwardProc(w, event, prms, nprms)
\r
6693 void ToStartProc(w, event, prms, nprms)
\r
6702 void ToEndProc(w, event, prms, nprms)
\r
6711 void RevertProc(w, event, prms, nprms)
\r
6720 void TruncateGameProc(w, event, prms, nprms)
\r
6726 TruncateGameEvent();
\r
6728 void RetractMoveProc(w, event, prms, nprms)
\r
6734 RetractMoveEvent();
\r
6737 void MoveNowProc(w, event, prms, nprms)
\r
6747 void AlwaysQueenProc(w, event, prms, nprms)
\r
6755 appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
\r
6757 if (appData.alwaysPromoteToQueen) {
\r
6758 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6760 XtSetArg(args[0], XtNleftBitmap, None);
\r
6762 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
\r
6766 void AnimateDraggingProc(w, event, prms, nprms)
\r
6774 appData.animateDragging = !appData.animateDragging;
\r
6776 if (appData.animateDragging) {
\r
6777 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6780 XtSetArg(args[0], XtNleftBitmap, None);
\r
6782 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
\r
6786 void AnimateMovingProc(w, event, prms, nprms)
\r
6794 appData.animate = !appData.animate;
\r
6796 if (appData.animate) {
\r
6797 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6800 XtSetArg(args[0], XtNleftBitmap, None);
\r
6802 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
\r
6806 void AutocommProc(w, event, prms, nprms)
\r
6814 appData.autoComment = !appData.autoComment;
\r
6816 if (appData.autoComment) {
\r
6817 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6819 XtSetArg(args[0], XtNleftBitmap, None);
\r
6821 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
\r
6826 void AutoflagProc(w, event, prms, nprms)
\r
6834 appData.autoCallFlag = !appData.autoCallFlag;
\r
6836 if (appData.autoCallFlag) {
\r
6837 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6839 XtSetArg(args[0], XtNleftBitmap, None);
\r
6841 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
\r
6845 void AutoflipProc(w, event, prms, nprms)
\r
6853 appData.autoFlipView = !appData.autoFlipView;
\r
6855 if (appData.autoFlipView) {
\r
6856 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6858 XtSetArg(args[0], XtNleftBitmap, None);
\r
6860 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),
\r
6864 void AutobsProc(w, event, prms, nprms)
\r
6872 appData.autoObserve = !appData.autoObserve;
\r
6874 if (appData.autoObserve) {
\r
6875 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6877 XtSetArg(args[0], XtNleftBitmap, None);
\r
6879 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
\r
6883 void AutoraiseProc(w, event, prms, nprms)
\r
6891 appData.autoRaiseBoard = !appData.autoRaiseBoard;
\r
6893 if (appData.autoRaiseBoard) {
\r
6894 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6896 XtSetArg(args[0], XtNleftBitmap, None);
\r
6898 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),
\r
6902 void AutosaveProc(w, event, prms, nprms)
\r
6910 appData.autoSaveGames = !appData.autoSaveGames;
\r
6912 if (appData.autoSaveGames) {
\r
6913 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6915 XtSetArg(args[0], XtNleftBitmap, None);
\r
6917 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
\r
6921 void BlindfoldProc(w, event, prms, nprms)
\r
6929 appData.blindfold = !appData.blindfold;
\r
6931 if (appData.blindfold) {
\r
6932 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6934 XtSetArg(args[0], XtNleftBitmap, None);
\r
6936 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),
\r
6939 DrawPosition(True, NULL);
\r
6942 void TestLegalityProc(w, event, prms, nprms)
\r
6950 appData.testLegality = !appData.testLegality;
\r
6952 if (appData.testLegality) {
\r
6953 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6955 XtSetArg(args[0], XtNleftBitmap, None);
\r
6957 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),
\r
6962 void FlashMovesProc(w, event, prms, nprms)
\r
6970 if (appData.flashCount == 0) {
\r
6971 appData.flashCount = 3;
\r
6973 appData.flashCount = -appData.flashCount;
\r
6976 if (appData.flashCount > 0) {
\r
6977 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
6979 XtSetArg(args[0], XtNleftBitmap, None);
\r
6981 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),
\r
6985 void FlipViewProc(w, event, prms, nprms)
\r
6991 flipView = !flipView;
\r
6992 DrawPosition(True, NULL);
\r
6995 void GetMoveListProc(w, event, prms, nprms)
\r
7003 appData.getMoveList = !appData.getMoveList;
\r
7005 if (appData.getMoveList) {
\r
7006 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7007 GetMoveListEvent();
\r
7009 XtSetArg(args[0], XtNleftBitmap, None);
\r
7011 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
\r
7016 void HighlightDraggingProc(w, event, prms, nprms)
\r
7024 appData.highlightDragging = !appData.highlightDragging;
\r
7026 if (appData.highlightDragging) {
\r
7027 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7029 XtSetArg(args[0], XtNleftBitmap, None);
\r
7031 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7032 "menuOptions.Highlight Dragging"), args, 1);
\r
7036 void HighlightLastMoveProc(w, event, prms, nprms)
\r
7044 appData.highlightLastMove = !appData.highlightLastMove;
\r
7046 if (appData.highlightLastMove) {
\r
7047 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7049 XtSetArg(args[0], XtNleftBitmap, None);
\r
7051 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7052 "menuOptions.Highlight Last Move"), args, 1);
\r
7055 void IcsAlarmProc(w, event, prms, nprms)
\r
7063 appData.icsAlarm = !appData.icsAlarm;
\r
7065 if (appData.icsAlarm) {
\r
7066 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7068 XtSetArg(args[0], XtNleftBitmap, None);
\r
7070 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7071 "menuOptions.ICS Alarm"), args, 1);
\r
7074 void MoveSoundProc(w, event, prms, nprms)
\r
7082 appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
\r
7084 if (appData.ringBellAfterMoves) {
\r
7085 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7087 XtSetArg(args[0], XtNleftBitmap, None);
\r
7089 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
\r
7094 void OldSaveStyleProc(w, event, prms, nprms)
\r
7102 appData.oldSaveStyle = !appData.oldSaveStyle;
\r
7104 if (appData.oldSaveStyle) {
\r
7105 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7107 XtSetArg(args[0], XtNleftBitmap, None);
\r
7109 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
\r
7113 void PeriodicUpdatesProc(w, event, prms, nprms)
\r
7121 PeriodicUpdatesEvent(!appData.periodicUpdates);
\r
7123 if (appData.periodicUpdates) {
\r
7124 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7126 XtSetArg(args[0], XtNleftBitmap, None);
\r
7128 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),
\r
7132 void PonderNextMoveProc(w, event, prms, nprms)
\r
7140 PonderNextMoveEvent(!appData.ponderNextMove);
\r
7142 if (appData.ponderNextMove) {
\r
7143 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7145 XtSetArg(args[0], XtNleftBitmap, None);
\r
7147 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
\r
7151 void PopupExitMessageProc(w, event, prms, nprms)
\r
7159 appData.popupExitMessage = !appData.popupExitMessage;
\r
7161 if (appData.popupExitMessage) {
\r
7162 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7164 XtSetArg(args[0], XtNleftBitmap, None);
\r
7166 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7167 "menuOptions.Popup Exit Message"), args, 1);
\r
7170 void PopupMoveErrorsProc(w, event, prms, nprms)
\r
7178 appData.popupMoveErrors = !appData.popupMoveErrors;
\r
7180 if (appData.popupMoveErrors) {
\r
7181 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7183 XtSetArg(args[0], XtNleftBitmap, None);
\r
7185 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),
\r
7189 void PremoveProc(w, event, prms, nprms)
\r
7197 appData.premove = !appData.premove;
\r
7199 if (appData.premove) {
\r
7200 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7202 XtSetArg(args[0], XtNleftBitmap, None);
\r
7204 XtSetValues(XtNameToWidget(menuBarWidget,
\r
7205 "menuOptions.Premove"), args, 1);
\r
7208 void QuietPlayProc(w, event, prms, nprms)
\r
7216 appData.quietPlay = !appData.quietPlay;
\r
7218 if (appData.quietPlay) {
\r
7219 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7221 XtSetArg(args[0], XtNleftBitmap, None);
\r
7223 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
\r
7227 void ShowCoordsProc(w, event, prms, nprms)
\r
7235 appData.showCoords = !appData.showCoords;
\r
7237 if (appData.showCoords) {
\r
7238 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7240 XtSetArg(args[0], XtNleftBitmap, None);
\r
7242 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
\r
7245 DrawPosition(True, NULL);
\r
7248 void ShowThinkingProc(w, event, prms, nprms)
\r
7256 appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
\r
7257 ShowThinkingEvent();
\r
7259 // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)
\r
7260 if (appData.showThinking) {
\r
7261 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7263 XtSetArg(args[0], XtNleftBitmap, None);
\r
7265 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
\r
7270 void HideThinkingProc(w, event, prms, nprms)
\r
7278 appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
\r
7279 ShowThinkingEvent();
\r
7281 if (appData.hideThinkingFromHuman) {
\r
7282 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
\r
7284 XtSetArg(args[0], XtNleftBitmap, None);
\r
7286 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
\r
7290 void InfoProc(w, event, prms, nprms)
\r
7296 char buf[MSG_SIZ];
\r
7297 sprintf(buf, "xterm -e info --directory %s --directory . -f %s &",
\r
7298 INFODIR, INFOFILE);
\r
7302 void ManProc(w, event, prms, nprms)
\r
7308 char buf[MSG_SIZ];
\r
7310 if (nprms && *nprms > 0)
\r
7314 sprintf(buf, "xterm -e man %s &", name);
\r
7318 void HintProc(w, event, prms, nprms)
\r
7327 void BookProc(w, event, prms, nprms)
\r
7336 void AboutProc(w, event, prms, nprms)
\r
7342 char buf[MSG_SIZ];
\r
7344 char *zippy = " (with Zippy code)";
\r
7348 sprintf(buf, "%s%s\n\n%s\n%s\n%s\n%s\n\n%s%s\n%s",
\r
7349 programVersion, zippy,
\r
7350 "Copyright 1991 Digital Equipment Corporation",
\r
7351 "Enhancements Copyright 1992-2001 Free Software Foundation",
\r
7352 "Enhancements Copyright 2005 Alessandro Scotti",
\r
7353 "Enhancements Copyright 2007-2008 H.G.Muller",
\r
7354 PRODUCT, " is free software and carries NO WARRANTY;",
\r
7355 "see the file COPYING for more information.");
\r
7356 ErrorPopUp(_("About XBoard"), buf, FALSE);
\r
7359 void DebugProc(w, event, prms, nprms)
\r
7365 appData.debugMode = !appData.debugMode;
\r
7368 void AboutGameProc(w, event, prms, nprms)
\r
7377 void NothingProc(w, event, prms, nprms)
\r
7386 void Iconify(w, event, prms, nprms)
\r
7394 fromX = fromY = -1;
\r
7395 XtSetArg(args[0], XtNiconic, True);
\r
7396 XtSetValues(shellWidget, args, 1);
\r
7399 void DisplayMessage(message, extMessage)
\r
7400 char *message, *extMessage;
\r
7402 char buf[MSG_SIZ];
\r
7407 sprintf(buf, "%s %s", message, extMessage);
\r
7410 message = extMessage;
\r
7413 XtSetArg(arg, XtNlabel, message);
\r
7414 XtSetValues(messageWidget, &arg, 1);
\r
7417 void DisplayTitle(text)
\r
7422 char title[MSG_SIZ];
\r
7423 char icon[MSG_SIZ];
\r
7425 if (text == NULL) text = "";
\r
7427 if (appData.titleInWindow) {
\r
7429 XtSetArg(args[i], XtNlabel, text); i++;
\r
7430 XtSetValues(titleWidget, args, i);
\r
7433 if (*text != NULLCHAR) {
\r
7434 strcpy(icon, text);
\r
7435 strcpy(title, text);
\r
7436 } else if (appData.icsActive) {
\r
7437 sprintf(icon, "%s", appData.icsHost);
\r
7438 sprintf(title, "%s: %s", programName, appData.icsHost);
\r
7439 } else if (appData.cmailGameName[0] != NULLCHAR) {
\r
7440 sprintf(icon, "%s", "CMail");
\r
7441 sprintf(title, "%s: %s", programName, "CMail");
\r
7443 // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
\r
7444 } else if (gameInfo.variant == VariantGothic) {
\r
7445 strcpy(icon, programName);
\r
7446 strcpy(title, GOTHIC);
\r
7449 } else if (gameInfo.variant == VariantFalcon) {
\r
7450 strcpy(icon, programName);
\r
7451 strcpy(title, FALCON);
\r
7453 } else if (appData.noChessProgram) {
\r
7454 strcpy(icon, programName);
\r
7455 strcpy(title, programName);
\r
7457 strcpy(icon, first.tidy);
\r
7458 sprintf(title, "%s: %s", programName, first.tidy);
\r
7461 XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++;
\r
7462 XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++;
\r
7463 XtSetValues(shellWidget, args, i);
\r
7467 void DisplayError(message, error)
\r
7471 char buf[MSG_SIZ];
\r
7474 if (appData.debugMode || appData.matchMode) {
\r
7475 fprintf(stderr, "%s: %s\n", programName, message);
\r
7478 if (appData.debugMode || appData.matchMode) {
\r
7479 fprintf(stderr, "%s: %s: %s\n",
\r
7480 programName, message, strerror(error));
\r
7482 sprintf(buf, "%s: %s", message, strerror(error));
\r
7485 ErrorPopUp(_("Error"), message, FALSE);
\r
7489 void DisplayMoveError(message)
\r
7492 fromX = fromY = -1;
\r
7493 ClearHighlights();
\r
7494 DrawPosition(FALSE, NULL);
\r
7495 if (appData.debugMode || appData.matchMode) {
\r
7496 fprintf(stderr, "%s: %s\n", programName, message);
\r
7498 if (appData.popupMoveErrors) {
\r
7499 ErrorPopUp(_("Error"), message, FALSE);
\r
7501 DisplayMessage(message, "");
\r
7506 void DisplayFatalError(message, error, status)
\r
7508 int error, status;
\r
7510 char buf[MSG_SIZ];
\r
7512 errorExitStatus = status;
\r
7514 fprintf(stderr, "%s: %s\n", programName, message);
\r
7516 fprintf(stderr, "%s: %s: %s\n",
\r
7517 programName, message, strerror(error));
\r
7518 sprintf(buf, "%s: %s", message, strerror(error));
\r
7521 if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
\r
7522 ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
\r
7524 ExitEvent(status);
\r
7528 void DisplayInformation(message)
\r
7532 ErrorPopUp(_("Information"), message, TRUE);
\r
7535 void DisplayNote(message)
\r
7539 ErrorPopUp(_("Note"), message, FALSE);
\r
7543 NullXErrorCheck(dpy, error_event)
\r
7545 XErrorEvent *error_event;
\r
7550 void DisplayIcsInteractionTitle(message)
\r
7553 if (oldICSInteractionTitle == NULL) {
\r
7554 /* Magic to find the old window title, adapted from vim */
\r
7555 char *wina = getenv("WINDOWID");
\r
7556 if (wina != NULL) {
\r
7557 Window win = (Window) atoi(wina);
\r
7558 Window root, parent, *children;
\r
7559 unsigned int nchildren;
\r
7560 int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);
\r
7562 if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
\r
7563 if (!XQueryTree(xDisplay, win, &root, &parent,
\r
7564 &children, &nchildren)) break;
\r
7565 if (children) XFree((void *)children);
\r
7566 if (parent == root || parent == 0) break;
\r
7569 XSetErrorHandler(oldHandler);
\r
7571 if (oldICSInteractionTitle == NULL) {
\r
7572 oldICSInteractionTitle = "xterm";
\r
7575 printf("\033]0;%s\007", message);
\r
7579 char pendingReplyPrefix[MSG_SIZ];
\r
7580 ProcRef pendingReplyPR;
\r
7582 void AskQuestionProc(w, event, prms, nprms)
\r
7588 if (*nprms != 4) {
\r
7589 fprintf(stderr, _("AskQuestionProc needed 4 parameters, got %d\n"),
\r
7593 AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);
\r
7596 void AskQuestionPopDown()
\r
7598 if (!askQuestionUp) return;
\r
7599 XtPopdown(askQuestionShell);
\r
7600 XtDestroyWidget(askQuestionShell);
\r
7601 askQuestionUp = False;
\r
7604 void AskQuestionReplyAction(w, event, prms, nprms)
\r
7610 char buf[MSG_SIZ];
\r
7614 reply = XawDialogGetValueString(w = XtParent(w));
\r
7615 strcpy(buf, pendingReplyPrefix);
\r
7616 if (*buf) strcat(buf, " ");
\r
7617 strcat(buf, reply);
\r
7618 strcat(buf, "\n");
\r
7619 OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
\r
7620 AskQuestionPopDown();
\r
7622 if (err) DisplayFatalError(_("Error writing to chess program"), err, 0);
\r
7625 void AskQuestionCallback(w, client_data, call_data)
\r
7627 XtPointer client_data, call_data;
\r
7632 XtSetArg(args[0], XtNlabel, &name);
\r
7633 XtGetValues(w, args, 1);
\r
7635 if (strcmp(name, _("cancel")) == 0) {
\r
7636 AskQuestionPopDown();
\r
7638 AskQuestionReplyAction(w, NULL, NULL, NULL);
\r
7642 void AskQuestion(title, question, replyPrefix, pr)
\r
7643 char *title, *question, *replyPrefix;
\r
7647 Widget popup, layout, dialog, edit;
\r
7648 Window root, child;
\r
7651 unsigned int mask;
\r
7653 strcpy(pendingReplyPrefix, replyPrefix);
\r
7654 pendingReplyPR = pr;
\r
7657 XtSetArg(args[i], XtNresizable, True); i++;
\r
7658 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
\r
7659 askQuestionShell = popup =
\r
7660 XtCreatePopupShell(title, transientShellWidgetClass,
\r
7661 shellWidget, args, i);
\r
7664 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
\r
7665 layoutArgs, XtNumber(layoutArgs));
\r
7668 XtSetArg(args[i], XtNlabel, question); i++;
\r
7669 XtSetArg(args[i], XtNvalue, ""); i++;
\r
7670 XtSetArg(args[i], XtNborderWidth, 0); i++;
\r
7671 dialog = XtCreateManagedWidget("question", dialogWidgetClass,
\r
7674 XawDialogAddButton(dialog, _("enter"), AskQuestionCallback,
\r
7675 (XtPointer) dialog);
\r
7676 XawDialogAddButton(dialog, _("cancel"), AskQuestionCallback,
\r
7677 (XtPointer) dialog);
\r
7679 XtRealizeWidget(popup);
\r
7680 CatchDeleteWindow(popup, "AskQuestionPopDown");
\r
7682 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
\r
7683 &x, &y, &win_x, &win_y, &mask);
\r
7685 XtSetArg(args[0], XtNx, x - 10);
\r
7686 XtSetArg(args[1], XtNy, y - 30);
\r
7687 XtSetValues(popup, args, 2);
\r
7689 XtPopup(popup, XtGrabExclusive);
\r
7690 askQuestionUp = True;
\r
7692 edit = XtNameToWidget(dialog, "*value");
\r
7693 XtSetKeyboardFocus(popup, edit);
\r
7701 if (*name == NULLCHAR) {
\r
7703 } else if (strcmp(name, "$") == 0) {
\r
7704 putc(BELLCHAR, stderr);
\r
7707 sprintf(buf, "%s '%s' &", appData.soundProgram, name);
\r
7715 PlaySound(appData.soundMove);
\r
7721 PlaySound(appData.soundIcsWin);
\r
7725 PlayIcsLossSound()
\r
7727 PlaySound(appData.soundIcsLoss);
\r
7731 PlayIcsDrawSound()
\r
7733 PlaySound(appData.soundIcsDraw);
\r
7737 PlayIcsUnfinishedSound()
\r
7739 PlaySound(appData.soundIcsUnfinished);
\r
7745 PlaySound(appData.soundIcsAlarm);
\r
7751 system("stty echo");
\r
7757 system("stty -echo");
\r
7761 Colorize(cc, continuation)
\r
7765 char buf[MSG_SIZ];
\r
7766 int count, outCount, error;
\r
7768 if (textColors[(int)cc].bg > 0) {
\r
7769 if (textColors[(int)cc].fg > 0) {
\r
7770 sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
\r
7771 textColors[(int)cc].fg, textColors[(int)cc].bg);
\r
7773 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
\r
7774 textColors[(int)cc].bg);
\r
7777 if (textColors[(int)cc].fg > 0) {
\r
7778 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
\r
7779 textColors[(int)cc].fg);
\r
7781 sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);
\r
7784 count = strlen(buf);
\r
7785 outCount = OutputToProcess(NoProc, buf, count, &error);
\r
7786 if (outCount < count) {
\r
7787 DisplayFatalError(_("Error writing to display"), error, 1);
\r
7790 if (continuation) return;
\r
7793 PlaySound(appData.soundShout);
\r
7796 PlaySound(appData.soundSShout);
\r
7798 case ColorChannel1:
\r
7799 PlaySound(appData.soundChannel1);
\r
7801 case ColorChannel:
\r
7802 PlaySound(appData.soundChannel);
\r
7805 PlaySound(appData.soundKibitz);
\r
7808 PlaySound(appData.soundTell);
\r
7810 case ColorChallenge:
\r
7811 PlaySound(appData.soundChallenge);
\r
7813 case ColorRequest:
\r
7814 PlaySound(appData.soundRequest);
\r
7817 PlaySound(appData.soundSeek);
\r
7828 return getpwuid(getuid())->pw_name;
\r
7831 static char *ExpandPathName(path)
\r
7834 static char static_buf[2000];
\r
7835 char *d, *s, buf[2000];
\r
7836 struct passwd *pwd;
\r
7841 while (*s && isspace(*s))
\r
7846 return static_buf;
\r
7850 if (*(s+1) == '/') {
\r
7851 strcpy(d, getpwuid(getuid())->pw_dir);
\r
7856 *strchr(buf, '/') = 0;
\r
7857 pwd = getpwnam(buf);
\r
7860 fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
\r
7864 strcpy(d, pwd->pw_dir);
\r
7865 strcat(d, strchr(s+1, '/'));
\r
7871 return static_buf;
\r
7876 static char host_name[MSG_SIZ];
\r
7878 #if HAVE_GETHOSTNAME
\r
7879 gethostname(host_name, MSG_SIZ);
\r
7881 #else /* not HAVE_GETHOSTNAME */
\r
7882 # if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
\r
7883 sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
\r
7885 # else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
\r
7886 return "localhost";
\r
7887 # endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
\r
7888 #endif /* not HAVE_GETHOSTNAME */
\r
7891 XtIntervalId delayedEventTimerXID = 0;
\r
7892 DelayedEventCallback delayedEventCallback = 0;
\r
7895 FireDelayedEvent()
\r
7897 delayedEventTimerXID = 0;
\r
7898 delayedEventCallback();
\r
7902 ScheduleDelayedEvent(cb, millisec)
\r
7903 DelayedEventCallback cb; long millisec;
\r
7905 delayedEventCallback = cb;
\r
7906 delayedEventTimerXID =
\r
7907 XtAppAddTimeOut(appContext, millisec,
\r
7908 (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
\r
7911 DelayedEventCallback
\r
7914 if (delayedEventTimerXID) {
\r
7915 return delayedEventCallback;
\r
7922 CancelDelayedEvent()
\r
7924 if (delayedEventTimerXID) {
\r
7925 XtRemoveTimeOut(delayedEventTimerXID);
\r
7926 delayedEventTimerXID = 0;
\r
7930 XtIntervalId loadGameTimerXID = 0;
\r
7932 int LoadGameTimerRunning()
\r
7934 return loadGameTimerXID != 0;
\r
7937 int StopLoadGameTimer()
\r
7939 if (loadGameTimerXID != 0) {
\r
7940 XtRemoveTimeOut(loadGameTimerXID);
\r
7941 loadGameTimerXID = 0;
\r
7949 LoadGameTimerCallback(arg, id)
\r
7953 loadGameTimerXID = 0;
\r
7954 AutoPlayGameLoop();
\r
7958 StartLoadGameTimer(millisec)
\r
7961 loadGameTimerXID =
\r
7962 XtAppAddTimeOut(appContext, millisec,
\r
7963 (XtTimerCallbackProc) LoadGameTimerCallback,
\r
7967 XtIntervalId analysisClockXID = 0;
\r
7970 AnalysisClockCallback(arg, id)
\r
7974 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
\r
7975 || appData.icsEngineAnalyze) { // [DM]
\r
7976 AnalysisPeriodicEvent(0);
\r
7977 StartAnalysisClock();
\r
7982 StartAnalysisClock()
\r
7984 analysisClockXID =
\r
7985 XtAppAddTimeOut(appContext, 2000,
\r
7986 (XtTimerCallbackProc) AnalysisClockCallback,
\r
7990 XtIntervalId clockTimerXID = 0;
\r
7992 int ClockTimerRunning()
\r
7994 return clockTimerXID != 0;
\r
7997 int StopClockTimer()
\r
7999 if (clockTimerXID != 0) {
\r
8000 XtRemoveTimeOut(clockTimerXID);
\r
8001 clockTimerXID = 0;
\r
8009 ClockTimerCallback(arg, id)
\r
8013 clockTimerXID = 0;
\r
8014 DecrementClocks();
\r
8018 StartClockTimer(millisec)
\r
8022 XtAppAddTimeOut(appContext, millisec,
\r
8023 (XtTimerCallbackProc) ClockTimerCallback,
\r
8028 DisplayTimerLabel(w, color, timer, highlight)
\r
8034 char buf[MSG_SIZ];
\r
8037 if (appData.clockMode) {
\r
8038 sprintf(buf, "%s: %s", color, TimeString(timer));
\r
8039 XtSetArg(args[0], XtNlabel, buf);
\r
8041 sprintf(buf, "%s ", color);
\r
8042 XtSetArg(args[0], XtNlabel, buf);
\r
8046 XtSetArg(args[1], XtNbackground, timerForegroundPixel);
\r
8047 XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
\r
8049 XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
\r
8050 XtSetArg(args[2], XtNforeground, timerForegroundPixel);
\r
8053 XtSetValues(w, args, 3);
\r
8057 DisplayWhiteClock(timeRemaining, highlight)
\r
8058 long timeRemaining;
\r
8063 if(appData.noGUI) return;
\r
8064 DisplayTimerLabel(whiteTimerWidget, _("White"), timeRemaining, highlight);
\r
8065 if (highlight && iconPixmap == bIconPixmap) {
\r
8066 iconPixmap = wIconPixmap;
\r
8067 XtSetArg(args[0], XtNiconPixmap, iconPixmap);
\r
8068 XtSetValues(shellWidget, args, 1);
\r
8073 DisplayBlackClock(timeRemaining, highlight)
\r
8074 long timeRemaining;
\r
8079 if(appData.noGUI) return;
\r
8080 DisplayTimerLabel(blackTimerWidget, _("Black"), timeRemaining, highlight);
\r
8081 if (highlight && iconPixmap == wIconPixmap) {
\r
8082 iconPixmap = bIconPixmap;
\r
8083 XtSetArg(args[0], XtNiconPixmap, iconPixmap);
\r
8084 XtSetValues(shellWidget, args, 1);
\r
8093 typedef int CPKind;
\r
8098 int fdTo, fdFrom;
\r
8102 int StartChildProcess(cmdLine, dir, pr)
\r
8107 char *argv[64], *p;
\r
8109 int to_prog[2], from_prog[2];
\r
8111 char buf[MSG_SIZ];
\r
8113 if (appData.debugMode) {
\r
8114 fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
\r
8117 /* We do NOT feed the cmdLine to the shell; we just
\r
8118 parse it into blank-separated arguments in the
\r
8119 most simple-minded way possible.
\r
8122 strcpy(buf, cmdLine);
\r
8126 p = strchr(p, ' ');
\r
8127 if (p == NULL) break;
\r
8132 SetUpChildIO(to_prog, from_prog);
\r
8134 if ((pid = fork()) == 0) {
\r
8135 /* Child process */
\r
8136 // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1
\r
8137 close(to_prog[1]); // first close the unused pipe ends
\r
8138 close(from_prog[0]);
\r
8139 dup2(to_prog[0], 0); // to_prog was created first, nd is the only one to use 0 or 1
\r
8140 dup2(from_prog[1], 1);
\r
8141 if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original
\r
8142 close(from_prog[1]); // and closing again loses one of the pipes!
\r
8143 if(fileno(stderr) >= 2) // better safe than sorry...
\r
8144 dup2(1, fileno(stderr)); /* force stderr to the pipe */
\r
8146 if (dir[0] != NULLCHAR && chdir(dir) != 0) {
\r
8151 nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc
\r
8153 execvp(argv[0], argv);
\r
8155 /* If we get here, exec failed */
\r
8160 /* Parent process */
\r
8161 close(to_prog[0]);
\r
8162 close(from_prog[1]);
\r
8164 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8165 cp->kind = CPReal;
\r
8167 cp->fdFrom = from_prog[0];
\r
8168 cp->fdTo = to_prog[1];
\r
8169 *pr = (ProcRef) cp;
\r
8173 // [HGM] kill: implement the 'hard killing' of AS's Winboard_x
\r
8174 static RETSIGTYPE AlarmCallBack(int n)
\r
8180 DestroyChildProcess(pr, signalType)
\r
8184 ChildProc *cp = (ChildProc *) pr;
\r
8186 if (cp->kind != CPReal) return;
\r
8187 cp->kind = CPNone;
\r
8188 if (signalType == 10) { // [HGM] kill: if it does not terminate in 3 sec, kill
\r
8189 signal(SIGALRM, AlarmCallBack);
\r
8191 if(wait((int *) 0) == -1) { // process does not terminate on its own accord
\r
8192 kill(cp->pid, SIGKILL); // kill it forcefully
\r
8193 wait((int *) 0); // and wait again
\r
8197 kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: use hard kill if so requested
\r
8199 /* Process is exiting either because of the kill or because of
\r
8200 a quit command sent by the backend; either way, wait for it to die.
\r
8204 close(cp->fdFrom);
\r
8209 InterruptChildProcess(pr)
\r
8212 ChildProc *cp = (ChildProc *) pr;
\r
8214 if (cp->kind != CPReal) return;
\r
8215 (void) kill(cp->pid, SIGINT); /* stop it thinking */
\r
8218 int OpenTelnet(host, port, pr)
\r
8223 char cmdLine[MSG_SIZ];
\r
8225 if (port[0] == NULLCHAR) {
\r
8226 sprintf(cmdLine, "%s %s", appData.telnetProgram, host);
\r
8228 sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);
\r
8230 return StartChildProcess(cmdLine, "", pr);
\r
8233 int OpenTCP(host, port, pr)
\r
8239 DisplayFatalError(_("Socket support is not configured in"), 0, 2);
\r
8240 #else /* !OMIT_SOCKETS */
\r
8242 struct sockaddr_in sa;
\r
8243 struct hostent *hp;
\r
8244 unsigned short uport;
\r
8247 if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
\r
8251 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
\r
8252 sa.sin_family = AF_INET;
\r
8253 sa.sin_addr.s_addr = INADDR_ANY;
\r
8254 uport = (unsigned short) 0;
\r
8255 sa.sin_port = htons(uport);
\r
8256 if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
\r
8260 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
\r
8261 if (!(hp = gethostbyname(host))) {
\r
8262 int b0, b1, b2, b3;
\r
8263 if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
\r
8264 hp = (struct hostent *) calloc(1, sizeof(struct hostent));
\r
8265 hp->h_addrtype = AF_INET;
\r
8267 hp->h_addr_list = (char **) calloc(2, sizeof(char *));
\r
8268 hp->h_addr_list[0] = (char *) malloc(4);
\r
8269 hp->h_addr_list[0][0] = b0;
\r
8270 hp->h_addr_list[0][1] = b1;
\r
8271 hp->h_addr_list[0][2] = b2;
\r
8272 hp->h_addr_list[0][3] = b3;
\r
8277 sa.sin_family = hp->h_addrtype;
\r
8278 uport = (unsigned short) atoi(port);
\r
8279 sa.sin_port = htons(uport);
\r
8280 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
\r
8282 if (connect(s, (struct sockaddr *) &sa,
\r
8283 sizeof(struct sockaddr_in)) < 0) {
\r
8287 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8288 cp->kind = CPSock;
\r
8292 *pr = (ProcRef) cp;
\r
8294 #endif /* !OMIT_SOCKETS */
\r
8299 int OpenCommPort(name, pr)
\r
8306 fd = open(name, 2, 0);
\r
8307 if (fd < 0) return errno;
\r
8309 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8310 cp->kind = CPComm;
\r
8314 *pr = (ProcRef) cp;
\r
8319 int OpenLoopback(pr)
\r
8323 int to[2], from[2];
\r
8325 SetUpChildIO(to, from);
\r
8327 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
\r
8328 cp->kind = CPLoop;
\r
8330 cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */
\r
8332 *pr = (ProcRef) cp;
\r
8337 int OpenRcmd(host, user, cmd, pr)
\r
8338 char *host, *user, *cmd;
\r
8341 DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
\r
8345 #define INPUT_SOURCE_BUF_SIZE 8192
\r
8352 InputCallback func;
\r
8354 char buf[INPUT_SOURCE_BUF_SIZE];
\r
8359 DoInputCallback(closure, source, xid)
\r
8364 InputSource *is = (InputSource *) closure;
\r
8369 if (is->lineByLine) {
\r
8370 count = read(is->fd, is->unused,
\r
8371 INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
\r
8373 (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
\r
8376 is->unused += count;
\r
8378 while (p < is->unused) {
\r
8379 q = memchr(p, '\n', is->unused - p);
\r
8380 if (q == NULL) break;
\r
8382 (is->func)(is, is->closure, p, q - p, 0);
\r
8386 while (p < is->unused) {
\r
8391 count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
\r
8396 (is->func)(is, is->closure, is->buf, count, error);
\r
8400 InputSourceRef AddInputSource(pr, lineByLine, func, closure)
\r
8403 InputCallback func;
\r
8407 ChildProc *cp = (ChildProc *) pr;
\r
8409 is = (InputSource *) calloc(1, sizeof(InputSource));
\r
8410 is->lineByLine = lineByLine;
\r
8412 if (pr == NoProc) {
\r
8413 is->kind = CPReal;
\r
8414 is->fd = fileno(stdin);
\r
8416 is->kind = cp->kind;
\r
8417 is->fd = cp->fdFrom;
\r
8420 is->unused = is->buf;
\r
8423 is->xid = XtAppAddInput(appContext, is->fd,
\r
8424 (XtPointer) (XtInputReadMask),
\r
8425 (XtInputCallbackProc) DoInputCallback,
\r
8427 is->closure = closure;
\r
8428 return (InputSourceRef) is;
\r
8432 RemoveInputSource(isr)
\r
8433 InputSourceRef isr;
\r
8435 InputSource *is = (InputSource *) isr;
\r
8437 if (is->xid == 0) return;
\r
8438 XtRemoveInput(is->xid);
\r
8442 int OutputToProcess(pr, message, count, outError)
\r
8448 ChildProc *cp = (ChildProc *) pr;
\r
8452 outCount = fwrite(message, 1, count, stdout);
\r
8454 outCount = write(cp->fdTo, message, count);
\r
8456 if (outCount == -1)
\r
8457 *outError = errno;
\r
8464 /* Output message to process, with "ms" milliseconds of delay
\r
8465 between each character. This is needed when sending the logon
\r
8466 script to ICC, which for some reason doesn't like the
\r
8467 instantaneous send. */
\r
8468 int OutputToProcessDelayed(pr, message, count, outError, msdelay)
\r
8475 ChildProc *cp = (ChildProc *) pr;
\r
8480 r = write(cp->fdTo, message++, 1);
\r
8482 *outError = errno;
\r
8487 TimeDelay(msdelay);
\r
8493 /**** Animation code by Hugh Fisher, DCS, ANU.
\r
8495 Known problem: if a window overlapping the board is
\r
8496 moved away while a piece is being animated underneath,
\r
8497 the newly exposed area won't be updated properly.
\r
8498 I can live with this.
\r
8500 Known problem: if you look carefully at the animation
\r
8501 of pieces in mono mode, they are being drawn as solid
\r
8502 shapes without interior detail while moving. Fixing
\r
8503 this would be a major complication for minimal return.
\r
8506 /* Masks for XPM pieces. Black and white pieces can have
\r
8507 different shapes, but in the interest of retaining my
\r
8508 sanity pieces must have the same outline on both light
\r
8509 and dark squares, and all pieces must use the same
\r
8510 background square colors/images. */
\r
8513 CreateAnimMasks (pieceDepth)
\r
8516 ChessSquare piece;
\r
8520 unsigned long plane;
\r
8523 /* Need a bitmap just to get a GC with right depth */
\r
8524 buf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8526 values.foreground = 1;
\r
8527 values.background = 0;
\r
8528 /* Don't use XtGetGC, not read only */
\r
8529 maskGC = XCreateGC(xDisplay, buf,
\r
8530 GCForeground | GCBackground, &values);
\r
8531 XFreePixmap(xDisplay, buf);
\r
8533 buf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8534 squareSize, squareSize, pieceDepth);
\r
8535 values.foreground = XBlackPixel(xDisplay, xScreen);
\r
8536 values.background = XWhitePixel(xDisplay, xScreen);
\r
8537 bufGC = XCreateGC(xDisplay, buf,
\r
8538 GCForeground | GCBackground, &values);
\r
8540 for (piece = WhitePawn; piece <= BlackKing; piece++) {
\r
8541 /* Begin with empty mask */
\r
8542 xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
\r
8543 squareSize, squareSize, 1);
\r
8544 XSetFunction(xDisplay, maskGC, GXclear);
\r
8545 XFillRectangle(xDisplay, xpmMask[piece], maskGC,
\r
8546 0, 0, squareSize, squareSize);
\r
8548 /* Take a copy of the piece */
\r
8553 XSetFunction(xDisplay, bufGC, GXcopy);
\r
8554 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
\r
8556 0, 0, squareSize, squareSize, 0, 0);
\r
8558 /* XOR the background (light) over the piece */
\r
8559 XSetFunction(xDisplay, bufGC, GXxor);
\r
8561 XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
\r
8562 0, 0, squareSize, squareSize, 0, 0);
\r
8564 XSetForeground(xDisplay, bufGC, lightSquareColor);
\r
8565 XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
\r
8568 /* We now have an inverted piece image with the background
\r
8569 erased. Construct mask by just selecting all the non-zero
\r
8570 pixels - no need to reconstruct the original image. */
\r
8571 XSetFunction(xDisplay, maskGC, GXor);
\r
8573 /* Might be quicker to download an XImage and create bitmap
\r
8574 data from it rather than this N copies per piece, but it
\r
8575 only takes a fraction of a second and there is a much
\r
8576 longer delay for loading the pieces. */
\r
8577 for (n = 0; n < pieceDepth; n ++) {
\r
8578 XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
\r
8579 0, 0, squareSize, squareSize,
\r
8581 plane = plane << 1;
\r
8585 XFreePixmap(xDisplay, buf);
\r
8586 XFreeGC(xDisplay, bufGC);
\r
8587 XFreeGC(xDisplay, maskGC);
\r
8591 InitAnimState (anim, info)
\r
8593 XWindowAttributes * info;
\r
8598 /* Each buffer is square size, same depth as window */
\r
8599 anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8600 squareSize, squareSize, info->depth);
\r
8601 anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
\r
8602 squareSize, squareSize, info->depth);
\r
8604 /* Create a plain GC for blitting */
\r
8605 mask = GCForeground | GCBackground | GCFunction |
\r
8606 GCPlaneMask | GCGraphicsExposures;
\r
8607 values.foreground = XBlackPixel(xDisplay, xScreen);
\r
8608 values.background = XWhitePixel(xDisplay, xScreen);
\r
8609 values.function = GXcopy;
\r
8610 values.plane_mask = AllPlanes;
\r
8611 values.graphics_exposures = False;
\r
8612 anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
\r
8614 /* Piece will be copied from an existing context at
\r
8615 the start of each new animation/drag. */
\r
8616 anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
\r
8618 /* Outline will be a read-only copy of an existing */
\r
8619 anim->outlineGC = None;
\r
8625 static int done = 0;
\r
8626 XWindowAttributes info;
\r
8630 XGetWindowAttributes(xDisplay, xBoardWindow, &info);
\r
8632 InitAnimState(&game, &info);
\r
8633 InitAnimState(&player, &info);
\r
8635 /* For XPM pieces, we need bitmaps to use as masks. */
\r
8637 CreateAnimMasks(info.depth);
\r
8640 #ifndef HAVE_USLEEP
\r
8642 static Boolean frameWaiting;
\r
8644 static RETSIGTYPE FrameAlarm (sig)
\r
8647 frameWaiting = False;
\r
8648 /* In case System-V style signals. Needed?? */
\r
8649 signal(SIGALRM, FrameAlarm);
\r
8656 struct itimerval delay;
\r
8658 XSync(xDisplay, False);
\r
8661 frameWaiting = True;
\r
8662 signal(SIGALRM, FrameAlarm);
\r
8663 delay.it_interval.tv_sec =
\r
8664 delay.it_value.tv_sec = time / 1000;
\r
8665 delay.it_interval.tv_usec =
\r
8666 delay.it_value.tv_usec = (time % 1000) * 1000;
\r
8667 setitimer(ITIMER_REAL, &delay, NULL);
\r
8669 /* Ugh -- busy-wait! --tpm */
\r
8670 while (frameWaiting);
\r
8672 while (frameWaiting) pause();
\r
8674 delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
\r
8675 delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
\r
8676 setitimer(ITIMER_REAL, &delay, NULL);
\r
8686 XSync(xDisplay, False);
\r
8688 usleep(time * 1000);
\r
8693 /* Convert board position to corner of screen rect and color */
\r
8696 ScreenSquare(column, row, pt, color)
\r
8697 int column; int row; XPoint * pt; int * color;
\r
8700 pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);
\r
8701 pt->y = lineGap + row * (squareSize + lineGap);
\r
8703 pt->x = lineGap + column * (squareSize + lineGap);
\r
8704 pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);
\r
8706 *color = SquareColor(row, column);
\r
8709 /* Convert window coords to square */
\r
8712 BoardSquare(x, y, column, row)
\r
8713 int x; int y; int * column; int * row;
\r
8715 *column = EventToSquare(x, BOARD_WIDTH);
\r
8716 if (flipView && *column >= 0)
\r
8717 *column = BOARD_WIDTH - 1 - *column;
\r
8718 *row = EventToSquare(y, BOARD_HEIGHT);
\r
8719 if (!flipView && *row >= 0)
\r
8720 *row = BOARD_HEIGHT - 1 - *row;
\r
8725 #undef Max /* just in case */
\r
8727 #define Max(a, b) ((a) > (b) ? (a) : (b))
\r
8728 #define Min(a, b) ((a) < (b) ? (a) : (b))
\r
8731 SetRect(rect, x, y, width, height)
\r
8732 XRectangle * rect; int x; int y; int width; int height;
\r
8736 rect->width = width;
\r
8737 rect->height = height;
\r
8740 /* Test if two frames overlap. If they do, return
\r
8741 intersection rect within old and location of
\r
8742 that rect within new. */
\r
8745 Intersect(old, new, size, area, pt)
\r
8746 XPoint * old; XPoint * new;
\r
8747 int size; XRectangle * area; XPoint * pt;
\r
8749 if (old->x > new->x + size || new->x > old->x + size ||
\r
8750 old->y > new->y + size || new->y > old->y + size) {
\r
8753 SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0),
\r
8754 size - abs(old->x - new->x), size - abs(old->y - new->y));
\r
8755 pt->x = Max(old->x - new->x, 0);
\r
8756 pt->y = Max(old->y - new->y, 0);
\r
8761 /* For two overlapping frames, return the rect(s)
\r
8762 in the old that do not intersect with the new. */
\r
8765 CalcUpdateRects(old, new, size, update, nUpdates)
\r
8766 XPoint * old; XPoint * new; int size;
\r
8767 XRectangle update[]; int * nUpdates;
\r
8771 /* If old = new (shouldn't happen) then nothing to draw */
\r
8772 if (old->x == new->x && old->y == new->y) {
\r
8776 /* Work out what bits overlap. Since we know the rects
\r
8777 are the same size we don't need a full intersect calc. */
\r
8779 /* Top or bottom edge? */
\r
8780 if (new->y > old->y) {
\r
8781 SetRect(&(update[count]), old->x, old->y, size, new->y - old->y);
\r
8783 } else if (old->y > new->y) {
\r
8784 SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y),
\r
8785 size, old->y - new->y);
\r
8788 /* Left or right edge - don't overlap any update calculated above. */
\r
8789 if (new->x > old->x) {
\r
8790 SetRect(&(update[count]), old->x, Max(new->y, old->y),
\r
8791 new->x - old->x, size - abs(new->y - old->y));
\r
8793 } else if (old->x > new->x) {
\r
8794 SetRect(&(update[count]), new->x + size, Max(new->y, old->y),
\r
8795 old->x - new->x, size - abs(new->y - old->y));
\r
8799 *nUpdates = count;
\r
8802 /* Generate a series of frame coords from start->mid->finish.
\r
8803 The movement rate doubles until the half way point is
\r
8804 reached, then halves back down to the final destination,
\r
8805 which gives a nice slow in/out effect. The algorithmn
\r
8806 may seem to generate too many intermediates for short
\r
8807 moves, but remember that the purpose is to attract the
\r
8808 viewers attention to the piece about to be moved and
\r
8809 then to where it ends up. Too few frames would be less
\r
8813 Tween(start, mid, finish, factor, frames, nFrames)
\r
8814 XPoint * start; XPoint * mid;
\r
8815 XPoint * finish; int factor;
\r
8816 XPoint frames[]; int * nFrames;
\r
8818 int fraction, n, count;
\r
8822 /* Slow in, stepping 1/16th, then 1/8th, ... */
\r
8824 for (n = 0; n < factor; n++)
\r
8826 for (n = 0; n < factor; n++) {
\r
8827 frames[count].x = start->x + (mid->x - start->x) / fraction;
\r
8828 frames[count].y = start->y + (mid->y - start->y) / fraction;
\r
8830 fraction = fraction / 2;
\r
8834 frames[count] = *mid;
\r
8837 /* Slow out, stepping 1/2, then 1/4, ... */
\r
8839 for (n = 0; n < factor; n++) {
\r
8840 frames[count].x = finish->x - (finish->x - mid->x) / fraction;
\r
8841 frames[count].y = finish->y - (finish->y - mid->y) / fraction;
\r
8843 fraction = fraction * 2;
\r
8848 /* Draw a piece on the screen without disturbing what's there */
\r
8851 SelectGCMask(piece, clip, outline, mask)
\r
8852 ChessSquare piece; GC * clip; GC * outline; Pixmap * mask;
\r
8856 /* Bitmap for piece being moved. */
\r
8857 if (appData.monoMode) {
\r
8858 *mask = *pieceToSolid(piece);
\r
8859 } else if (useImages) {
\r
8861 *mask = xpmMask[piece];
\r
8863 *mask = ximMaskPm[piece%(int)BlackPawn];
\r
8866 *mask = *pieceToSolid(piece);
\r
8869 /* GC for piece being moved. Square color doesn't matter, but
\r
8870 since it gets modified we make a copy of the original. */
\r
8871 if (White(piece)) {
\r
8872 if (appData.monoMode)
\r
8873 source = bwPieceGC;
\r
8875 source = wlPieceGC;
\r
8877 if (appData.monoMode)
\r
8878 source = wbPieceGC;
\r
8880 source = blPieceGC;
\r
8882 XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
\r
8884 /* Outline only used in mono mode and is not modified */
\r
8886 *outline = bwPieceGC;
\r
8888 *outline = wbPieceGC;
\r
8892 OverlayPiece(piece, clip, outline, dest)
\r
8893 ChessSquare piece; GC clip; GC outline; Drawable dest;
\r
8898 /* Draw solid rectangle which will be clipped to shape of piece */
\r
8899 XFillRectangle(xDisplay, dest, clip,
\r
8900 0, 0, squareSize, squareSize);
\r
8901 if (appData.monoMode)
\r
8902 /* Also draw outline in contrasting color for black
\r
8903 on black / white on white cases */
\r
8904 XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
\r
8905 0, 0, squareSize, squareSize, 0, 0, 1);
\r
8907 /* Copy the piece */
\r
8912 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
\r
8914 0, 0, squareSize, squareSize,
\r
8919 /* Animate the movement of a single piece */
\r
8922 BeginAnimation(anim, piece, startColor, start)
\r
8924 ChessSquare piece;
\r
8930 /* The old buffer is initialised with the start square (empty) */
\r
8931 BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);
\r
8932 anim->prevFrame = *start;
\r
8934 /* The piece will be drawn using its own bitmap as a matte */
\r
8935 SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
\r
8936 XSetClipMask(xDisplay, anim->pieceGC, mask);
\r
8940 AnimationFrame(anim, frame, piece)
\r
8943 ChessSquare piece;
\r
8945 XRectangle updates[4];
\r
8946 XRectangle overlap;
\r
8950 /* Save what we are about to draw into the new buffer */
\r
8951 XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
\r
8952 frame->x, frame->y, squareSize, squareSize,
\r
8955 /* Erase bits of the previous frame */
\r
8956 if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {
\r
8957 /* Where the new frame overlapped the previous,
\r
8958 the contents in newBuf are wrong. */
\r
8959 XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
\r
8960 overlap.x, overlap.y,
\r
8961 overlap.width, overlap.height,
\r
8963 /* Repaint the areas in the old that don't overlap new */
\r
8964 CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);
\r
8965 for (i = 0; i < count; i++)
\r
8966 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8967 updates[i].x - anim->prevFrame.x,
\r
8968 updates[i].y - anim->prevFrame.y,
\r
8969 updates[i].width, updates[i].height,
\r
8970 updates[i].x, updates[i].y);
\r
8972 /* Easy when no overlap */
\r
8973 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
8974 0, 0, squareSize, squareSize,
\r
8975 anim->prevFrame.x, anim->prevFrame.y);
\r
8978 /* Save this frame for next time round */
\r
8979 XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
\r
8980 0, 0, squareSize, squareSize,
\r
8982 anim->prevFrame = *frame;
\r
8984 /* Draw piece over original screen contents, not current,
\r
8985 and copy entire rect. Wipes out overlapping piece images. */
\r
8986 OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);
\r
8987 XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
\r
8988 0, 0, squareSize, squareSize,
\r
8989 frame->x, frame->y);
\r
8993 EndAnimation (anim, finish)
\r
8997 XRectangle updates[4];
\r
8998 XRectangle overlap;
\r
9002 /* The main code will redraw the final square, so we
\r
9003 only need to erase the bits that don't overlap. */
\r
9004 if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {
\r
9005 CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);
\r
9006 for (i = 0; i < count; i++)
\r
9007 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
9008 updates[i].x - anim->prevFrame.x,
\r
9009 updates[i].y - anim->prevFrame.y,
\r
9010 updates[i].width, updates[i].height,
\r
9011 updates[i].x, updates[i].y);
\r
9013 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
\r
9014 0, 0, squareSize, squareSize,
\r
9015 anim->prevFrame.x, anim->prevFrame.y);
\r
9020 FrameSequence(anim, piece, startColor, start, finish, frames, nFrames)
\r
9022 ChessSquare piece; int startColor;
\r
9023 XPoint * start; XPoint * finish;
\r
9024 XPoint frames[]; int nFrames;
\r
9028 BeginAnimation(anim, piece, startColor, start);
\r
9029 for (n = 0; n < nFrames; n++) {
\r
9030 AnimationFrame(anim, &(frames[n]), piece);
\r
9031 FrameDelay(appData.animSpeed);
\r
9033 EndAnimation(anim, finish);
\r
9036 /* Main control logic for deciding what to animate and how */
\r
9039 AnimateMove(board, fromX, fromY, toX, toY)
\r
9046 ChessSquare piece;
\r
9048 XPoint start, finish, mid;
\r
9049 XPoint frames[kFactor * 2 + 1];
\r
9050 int nFrames, startColor, endColor;
\r
9052 /* Are we animating? */
\r
9053 if (!appData.animate || appData.blindfold)
\r
9056 if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
\r
9057 piece = board[fromY][fromX];
\r
9058 if (piece >= EmptySquare) return;
\r
9063 hop = (piece == WhiteKnight || piece == BlackKnight);
\r
9066 if (appData.debugMode) {
\r
9067 fprintf(debugFP, hop ? _("AnimateMove: piece %d hops from %d,%d to %d,%d \n") :
\r
9068 _("AnimateMove: piece %d slides from %d,%d to %d,%d \n"),
\r
9069 piece, fromX, fromY, toX, toY); }
\r
9071 ScreenSquare(fromX, fromY, &start, &startColor);
\r
9072 ScreenSquare(toX, toY, &finish, &endColor);
\r
9075 /* Knight: make diagonal movement then straight */
\r
9076 if (abs(toY - fromY) < abs(toX - fromX)) {
\r
9077 mid.x = start.x + (finish.x - start.x) / 2;
\r
9081 mid.y = start.y + (finish.y - start.y) / 2;
\r
9084 mid.x = start.x + (finish.x - start.x) / 2;
\r
9085 mid.y = start.y + (finish.y - start.y) / 2;
\r
9088 /* Don't use as many frames for very short moves */
\r
9089 if (abs(toY - fromY) + abs(toX - fromX) <= 2)
\r
9090 Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);
\r
9092 Tween(&start, &mid, &finish, kFactor, frames, &nFrames);
\r
9093 FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
\r
9095 /* Be sure end square is redrawn */
\r
9096 damage[toY][toX] = True;
\r
9100 DragPieceBegin(x, y)
\r
9103 int boardX, boardY, color;
\r
9106 /* Are we animating? */
\r
9107 if (!appData.animateDragging || appData.blindfold)
\r
9110 /* Figure out which square we start in and the
\r
9111 mouse position relative to top left corner. */
\r
9112 BoardSquare(x, y, &boardX, &boardY);
\r
9113 player.startBoardX = boardX;
\r
9114 player.startBoardY = boardY;
\r
9115 ScreenSquare(boardX, boardY, &corner, &color);
\r
9116 player.startSquare = corner;
\r
9117 player.startColor = color;
\r
9119 /* Start from exactly where the piece is. This can be confusing
\r
9120 if you start dragging far from the center of the square; most
\r
9121 or all of the piece can be over a different square from the one
\r
9122 the mouse pointer is in. */
\r
9123 player.mouseDelta.x = x - corner.x;
\r
9124 player.mouseDelta.y = y - corner.y;
\r
9126 /* As soon as we start dragging, the piece will jump slightly to
\r
9127 be centered over the mouse pointer. */
\r
9128 player.mouseDelta.x = squareSize/2;
\r
9129 player.mouseDelta.y = squareSize/2;
\r
9131 /* Initialise animation */
\r
9132 player.dragPiece = PieceForSquare(boardX, boardY);
\r
9133 /* Sanity check */
\r
9134 if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {
\r
9135 player.dragActive = True;
\r
9136 BeginAnimation(&player, player.dragPiece, color, &corner);
\r
9137 /* Mark this square as needing to be redrawn. Note that
\r
9138 we don't remove the piece though, since logically (ie
\r
9139 as seen by opponent) the move hasn't been made yet. */
\r
9140 damage[boardY][boardX] = True;
\r
9142 player.dragActive = False;
\r
9147 DragPieceMove(x, y)
\r
9152 /* Are we animating? */
\r
9153 if (!appData.animateDragging || appData.blindfold)
\r
9156 /* Sanity check */
\r
9157 if (! player.dragActive)
\r
9159 /* Move piece, maintaining same relative position
\r
9160 of mouse within square */
\r
9161 corner.x = x - player.mouseDelta.x;
\r
9162 corner.y = y - player.mouseDelta.y;
\r
9163 AnimationFrame(&player, &corner, player.dragPiece);
\r
9165 if (appData.highlightDragging) {
\r
9166 int boardX, boardY;
\r
9167 BoardSquare(x, y, &boardX, &boardY);
\r
9168 SetHighlights(fromX, fromY, boardX, boardY);
\r
9174 DragPieceEnd(x, y)
\r
9177 int boardX, boardY, color;
\r
9180 /* Are we animating? */
\r
9181 if (!appData.animateDragging || appData.blindfold)
\r
9184 /* Sanity check */
\r
9185 if (! player.dragActive)
\r
9187 /* Last frame in sequence is square piece is
\r
9188 placed on, which may not match mouse exactly. */
\r
9189 BoardSquare(x, y, &boardX, &boardY);
\r
9190 ScreenSquare(boardX, boardY, &corner, &color);
\r
9191 EndAnimation(&player, &corner);
\r
9193 /* Be sure end square is redrawn */
\r
9194 damage[boardY][boardX] = True;
\r
9196 /* This prevents weird things happening with fast successive
\r
9197 clicks which on my Sun at least can cause motion events
\r
9198 without corresponding press/release. */
\r
9199 player.dragActive = False;
\r
9202 /* Handle expose event while piece being dragged */
\r
9207 if (!player.dragActive || appData.blindfold)
\r
9210 /* What we're doing: logically, the move hasn't been made yet,
\r
9211 so the piece is still in it's original square. But visually
\r
9212 it's being dragged around the board. So we erase the square
\r
9213 that the piece is on and draw it at the last known drag point. */
\r
9214 BlankSquare(player.startSquare.x, player.startSquare.y,
\r
9215 player.startColor, EmptySquare, xBoardWindow);
\r
9216 AnimationFrame(&player, &player.prevFrame, player.dragPiece);
\r
9217 damage[player.startBoardY][player.startBoardX] = TRUE;
\r
9221 SetProgramStats( FrontEndProgramStats * stats )
\r
9224 // [HGM] done, but perhaps backend should call this directly?
\r
9225 EngineOutputUpdate( stats );
\r