2 * xboard.c -- X front end for XBoard
4 * Copyright 1991 by Digital Equipment Corporation, Maynard,
7 * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
8 * 2007, 2008, 2009 Free Software Foundation, Inc.
10 * The following terms apply to Digital Equipment Corporation's copyright
12 * ------------------------------------------------------------------------
15 * Permission to use, copy, modify, and distribute this software and its
16 * documentation for any purpose and without fee is hereby granted,
17 * provided that the above copyright notice appear in all copies and that
18 * both that copyright notice and this permission notice appear in
19 * supporting documentation, and that the name of Digital not be
20 * used in advertising or publicity pertaining to distribution of the
21 * software without specific, written prior permission.
23 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
26 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
30 * ------------------------------------------------------------------------
32 * The following terms apply to the enhanced version of XBoard
33 * distributed by the Free Software Foundation:
34 * ------------------------------------------------------------------------
36 * GNU XBoard is free software: you can redistribute it and/or modify
37 * it under the terms of the GNU General Public License as published by
38 * the Free Software Foundation, either version 3 of the License, or (at
39 * your option) any later version.
41 * GNU XBoard is distributed in the hope that it will be useful, but
42 * WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44 * General Public License for more details.
46 * You should have received a copy of the GNU General Public License
47 * along with this program. If not, see http://www.gnu.org/licenses/. *
49 *------------------------------------------------------------------------
50 ** See the file ChangeLog for a revision history. */
58 #include <sys/types.h>
63 # if HAVE_SYS_SOCKET_H
64 # include <sys/socket.h>
65 # include <netinet/in.h>
67 # else /* not HAVE_SYS_SOCKET_H */
68 # if HAVE_LAN_SOCKET_H
69 # include <lan/socket.h>
71 # include <lan/netdb.h>
72 # else /* not HAVE_LAN_SOCKET_H */
73 # define OMIT_SOCKETS 1
74 # endif /* not HAVE_LAN_SOCKET_H */
75 # endif /* not HAVE_SYS_SOCKET_H */
76 #endif /* !OMIT_SOCKETS */
81 #else /* not STDC_HEADERS */
82 extern char *getenv();
85 # else /* not HAVE_STRING_H */
87 # endif /* not HAVE_STRING_H */
88 #endif /* not STDC_HEADERS */
91 # include <sys/fcntl.h>
92 #else /* not HAVE_SYS_FCNTL_H */
95 # endif /* HAVE_FCNTL_H */
96 #endif /* not HAVE_SYS_FCNTL_H */
98 #if HAVE_SYS_SYSTEMINFO_H
99 # include <sys/systeminfo.h>
100 #endif /* HAVE_SYS_SYSTEMINFO_H */
102 #if TIME_WITH_SYS_TIME
103 # include <sys/time.h>
107 # include <sys/time.h>
118 # include <sys/wait.h>
123 # define NAMLEN(dirent) strlen((dirent)->d_name)
124 # define HAVE_DIR_STRUCT
126 # define dirent direct
127 # define NAMLEN(dirent) (dirent)->d_namlen
129 # include <sys/ndir.h>
130 # define HAVE_DIR_STRUCT
133 # include <sys/dir.h>
134 # define HAVE_DIR_STRUCT
138 # define HAVE_DIR_STRUCT
142 #include <X11/Intrinsic.h>
143 #include <X11/StringDefs.h>
144 #include <X11/Shell.h>
145 #include <X11/cursorfont.h>
146 #include <X11/Xatom.h>
148 #include <X11/Xaw3d/Dialog.h>
149 #include <X11/Xaw3d/Form.h>
150 #include <X11/Xaw3d/List.h>
151 #include <X11/Xaw3d/Label.h>
152 #include <X11/Xaw3d/SimpleMenu.h>
153 #include <X11/Xaw3d/SmeBSB.h>
154 #include <X11/Xaw3d/SmeLine.h>
155 #include <X11/Xaw3d/Box.h>
156 #include <X11/Xaw3d/MenuButton.h>
157 #include <X11/Xaw3d/Text.h>
158 #include <X11/Xaw3d/AsciiText.h>
160 #include <X11/Xaw/Dialog.h>
161 #include <X11/Xaw/Form.h>
162 #include <X11/Xaw/List.h>
163 #include <X11/Xaw/Label.h>
164 #include <X11/Xaw/SimpleMenu.h>
165 #include <X11/Xaw/SmeBSB.h>
166 #include <X11/Xaw/SmeLine.h>
167 #include <X11/Xaw/Box.h>
168 #include <X11/Xaw/MenuButton.h>
169 #include <X11/Xaw/Text.h>
170 #include <X11/Xaw/AsciiText.h>
173 // [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
178 #include "pixmaps/pixmaps.h"
179 #define IMAGE_EXT "xpm"
181 #define IMAGE_EXT "xim"
182 #include "bitmaps/bitmaps.h"
187 #include <gdk-pixbuf/gdk-pixbuf.h>
189 #include "bitmaps/icon_white.bm"
190 #include "bitmaps/icon_black.bm"
191 #include "bitmaps/checkmark.bm"
193 #include "frontend.h"
198 #include "xgamelist.h"
199 #include "xhistory.h"
200 #include "xedittags.h"
202 #include "callback.h"
203 #include "interface.h"
205 // must be moved to xengineoutput.h
207 void EngineOutputProc P((Widget w, XEvent *event,
208 String *prms, Cardinal *nprms));
210 void EngineOutputPopDown();
217 #define usleep(t) _sleep2(((t)+500)/1000)
221 # define _(s) gettext (s)
222 # define N_(s) gettext_noop (s)
238 int main P((int argc, char **argv));
239 RETSIGTYPE CmailSigHandler P((int sig));
240 RETSIGTYPE IntSigHandler P((int sig));
241 void CreateGCs P((void));
242 void CreateXIMPieces P((void));
243 void CreateXPMPieces P((void));
244 void CreatePieces P((void));
245 void CreatePieceMenus P((void));
246 Widget CreateMenuBar P((Menu *mb));
247 Widget CreateButtonBar P ((MenuItem *mi));
248 char *FindFont P((char *pattern, int targetPxlSize));
249 void PieceMenuPopup P((Widget w, XEvent *event,
250 String *params, Cardinal *num_params));
251 static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
252 static void DropMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
253 void CreateGrid P((void));
254 int EventToSquare P((int x, int limit));
255 void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
256 void HandleUserMove P((Widget w, XEvent *event,
257 String *prms, Cardinal *nprms));
258 void AnimateUserMove P((Widget w, XEvent * event,
259 String * params, Cardinal * nParams));
260 void WhiteClock P((Widget w, XEvent *event,
261 String *prms, Cardinal *nprms));
262 void BlackClock P((Widget w, XEvent *event,
263 String *prms, Cardinal *nprms));
264 void DrawPositionProc P((Widget w, XEvent *event,
265 String *prms, Cardinal *nprms));
266 void CommentPopUp P((char *title, char *label));
267 void CommentPopDown P((void));
268 void CommentCallback P((Widget w, XtPointer client_data,
269 XtPointer call_data));
270 void ICSInputBoxPopUp P((void));
271 void ICSInputBoxPopDown P((void));
272 void FileNamePopUp P((char *label, char *def,
273 FileProc proc, char *openMode));
274 void FileNamePopDown P((void));
275 void FileNameCallback P((Widget w, XtPointer client_data,
276 XtPointer call_data));
277 void FileNameAction P((Widget w, XEvent *event,
278 String *prms, Cardinal *nprms));
279 void AskQuestionReplyAction P((Widget w, XEvent *event,
280 String *prms, Cardinal *nprms));
281 void AskQuestionProc P((Widget w, XEvent *event,
282 String *prms, Cardinal *nprms));
283 void AskQuestionPopDown P((void));
284 void PromotionPopUp P((void));
285 void PromotionPopDown P((void));
286 void PromotionCallback P((Widget w, XtPointer client_data,
287 XtPointer call_data));
288 void EditCommentPopDown P((void));
289 void EditCommentCallback P((Widget w, XtPointer client_data,
290 XtPointer call_data));
291 void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
292 void LoadPositionProc P((Widget w, XEvent *event,
293 String *prms, Cardinal *nprms));
294 void LoadNextPositionProc P((Widget w, XEvent *event, String *prms,
296 void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms,
298 void ReloadPositionProc P((Widget w, XEvent *event, String *prms,
300 void CopyPositionProc P((Widget w, XEvent *event, String *prms,
302 void PastePositionProc P((Widget w, XEvent *event, String *prms,
304 void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
305 void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
306 void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
307 void SavePositionProc P((Widget w, XEvent *event,
308 String *prms, Cardinal *nprms));
309 void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
310 void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
312 void MachineBlackProc P((Widget w, XEvent *event, String *prms,
314 void MachineWhiteProc P((Widget w, XEvent *event,
315 String *prms, Cardinal *nprms));
316 void AnalyzeModeProc P((Widget w, XEvent *event,
317 String *prms, Cardinal *nprms));
318 void AnalyzeFileProc P((Widget w, XEvent *event,
319 String *prms, Cardinal *nprms));
320 void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
322 void IcsClientProc P((Widget w, XEvent *event, String *prms,
324 void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
325 void EditPositionProc P((Widget w, XEvent *event,
326 String *prms, Cardinal *nprms));
327 void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
328 void EditCommentProc P((Widget w, XEvent *event,
329 String *prms, Cardinal *nprms));
330 void IcsInputBoxProc P((Widget w, XEvent *event,
331 String *prms, Cardinal *nprms));
332 void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
333 void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
334 void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
335 void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
336 void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
337 void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
338 void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
339 void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
340 void AdjuWhiteProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
341 void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
342 void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
343 void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
344 void StopObservingProc P((Widget w, XEvent *event, String *prms,
346 void StopExaminingProc P((Widget w, XEvent *event, String *prms,
348 void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
349 void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
350 void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
351 void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
352 void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
353 void TruncateGameProc P((Widget w, XEvent *event, String *prms,
355 void RetractMoveProc P((Widget w, XEvent *event, String *prms,
357 void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
358 void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
360 void AnimateDraggingProc P((Widget w, XEvent *event, String *prms,
362 void AnimateMovingProc P((Widget w, XEvent *event, String *prms,
364 void AutocommProc P((Widget w, XEvent *event, String *prms,
366 void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
367 void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
368 void AutobsProc P((Widget w, XEvent *event, String *prms,
370 void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
371 void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
372 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
373 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
375 void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
376 void GetMoveListProc P((Widget w, XEvent *event, String *prms,
378 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
380 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
382 void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
383 void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
384 void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
386 void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
388 void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
390 void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms,
392 void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
394 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
395 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
396 void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
398 void HideThinkingProc P((Widget w, XEvent *event, String *prms,
400 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
402 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
403 void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
404 void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
405 void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
406 void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
407 void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
408 void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
409 void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
410 void DisplayMove P((int moveNumber));
411 void DisplayTitle P((char *title));
412 void ICSInitScript P((void));
413 int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
414 void ErrorPopUp P((char *title, char *text, int modal));
415 void ErrorPopDown P((void));
416 static char *ExpandPathName P((char *path));
417 static void CreateAnimVars P((void));
418 void DragPieceBegin P((int x, int y));
419 static void DragPieceMove P((int x, int y));
420 void DragPieceEnd P((int x, int y));
421 static void DrawDragPiece P((void));
422 char *ModeToWidgetName P((GameMode mode));
423 void EngineOutputUpdate( FrontEndProgramStats * stats );
424 void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
425 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
426 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
427 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
428 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
429 void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
430 void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
431 void ShufflePopDown P(());
432 void EnginePopDown P(());
433 void UciPopDown P(());
434 void TimeControlPopDown P(());
435 void NewVariantPopDown P(());
436 void SettingsPopDown P(());
438 * XBoard depends on Xt R4 or higher
440 int xtVersion = XtSpecificationRelease;
445 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
446 jailSquareColor, highlightSquareColor, premoveHighlightColor;
447 Pixel lowTimeWarningColor;
448 GC lightSquareGC, darkSquareGC, jailSquareGC, lineGC, wdPieceGC, wlPieceGC,
449 bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC, highlineGC,
450 wjPieceGC, bjPieceGC, prelineGC, countGC;
451 Pixmap iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
452 Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
453 whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16],
454 commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
455 menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
456 ICSInputShell, fileNameShell, askQuestionShell;
457 GdkSegment gridSegments[(BOARD_SIZE + 1) * 2];
458 XSegment jailGridSegments[(BOARD_SIZE + 3) * 2];
459 Font clockFontID, coordFontID, countFontID;
460 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
461 XtAppContext appContext;
463 char *oldICSInteractionTitle;
467 char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
469 Position commentX = -1, commentY = -1;
470 Dimension commentW, commentH;
472 int squareSize, smallLayout = 0, tinyLayout = 0,
473 marginW, marginH, // [HGM] for run-time resizing
474 fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False,
475 ICSInputBoxUp = False, askQuestionUp = False,
476 filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1,
477 editUp = False, errorUp = False, errorExitStatus = -1, lineGap;
478 Pixel timerForegroundPixel, timerBackgroundPixel;
479 Pixel buttonForegroundPixel, buttonBackgroundPixel;
480 char *chessDir, *programName, *programVersion,
481 *gameCopyFilename, *gamePasteFilename;
485 Pixmap pieceBitmap[2][(int)BlackPawn];
486 Pixmap pieceBitmap2[2][(int)BlackPawn+4]; /* [HGM] pieces */
487 Pixmap xpmPieceBitmap[4][(int)BlackPawn]; /* LL, LD, DL, DD actually used*/
488 Pixmap xpmPieceBitmap2[4][(int)BlackPawn+4]; /* LL, LD, DL, DD set to select from */
489 Pixmap xpmLightSquare, xpmDarkSquare, xpmJailSquare;
490 int useImages=0, useImageSqs;
491 XImage *ximPieceBitmap[4][(int)BlackPawn+4]; /* LL, LD, DL, DD */
492 Pixmap ximMaskPm[(int)BlackPawn]; /* clipmasks, used for XIM pieces */
493 Pixmap ximMaskPm2[(int)BlackPawn+4]; /* clipmasks, used for XIM pieces */
494 XImage *ximLightSquare, *ximDarkSquare;
497 #define pieceToSolid(piece) &pieceBitmap[SOLID][(piece) % (int)BlackPawn]
498 #define pieceToOutline(piece) &pieceBitmap[OUTLINE][(piece) % (int)BlackPawn]
500 #define White(piece) ((int)(piece) < (int)BlackPawn)
502 /* Variables for doing smooth animation. This whole thing
503 would be much easier if the board was double-buffered,
504 but that would require a fairly major rewrite. */
509 GC blitGC, pieceGC, outlineGC;
510 XPoint startSquare, prevFrame, mouseDelta;
514 int startBoardX, startBoardY;
517 /* There can be two pieces being animated at once: a player
518 can begin dragging a piece before the remote opponent has moved. */
520 static AnimState game, player;
522 /* Bitmaps for use as masks when drawing XPM pieces.
523 Need one for each black and white piece. */
524 static Pixmap xpmMask[BlackKing + 1];
526 /* This magic number is the number of intermediate frames used
527 in each half of the animation. For short moves it's reduced
528 by 1. The total number of frames will be factor * 2 + 1. */
531 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
533 MenuItem fileMenu[] = {
534 {N_("New Shuffle Game ..."), ShuffleMenuProc},
535 {N_("New Variant ..."), NewVariantProc}, // [HGM] variant: not functional yet
536 {"----", NothingProc},
537 {N_("Save Game"), SaveGameProc},
538 {"----", NothingProc},
539 {N_("Copy Game"), CopyGameProc},
540 {N_("Paste Game"), PasteGameProc},
541 {"----", NothingProc},
542 {N_("Load Position"), LoadPositionProc},
543 {N_("Load Next Position"), LoadNextPositionProc},
544 {N_("Load Previous Position"), LoadPrevPositionProc},
545 {N_("Reload Same Position"), ReloadPositionProc},
546 {N_("Save Position"), SavePositionProc},
547 {"----", NothingProc},
548 {N_("Copy Position"), CopyPositionProc},
549 {N_("Paste Position"), PastePositionProc},
550 {"----", NothingProc},
551 {N_("Mail Move"), MailMoveProc},
552 {N_("Reload CMail Message"), ReloadCmailMsgProc},
553 {"----", NothingProc},
557 MenuItem modeMenu[] = {
558 {N_("Machine White"), MachineWhiteProc},
559 {N_("Machine Black"), MachineBlackProc},
560 {N_("Two Machines"), TwoMachinesProc},
561 {N_("Analysis Mode"), AnalyzeModeProc},
562 {N_("Analyze File"), AnalyzeFileProc },
563 {N_("ICS Client"), IcsClientProc},
564 {N_("Edit Game"), EditGameProc},
565 {N_("Edit Position"), EditPositionProc},
566 {N_("Training"), TrainingProc},
567 {"----", NothingProc},
568 {N_("Show Engine Output"), EngineOutputProc},
569 {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
570 {N_("Show Game List"), ShowGameListProc},
571 {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
572 {"----", NothingProc},
573 {N_("Edit Tags"), EditTagsProc},
574 {N_("Edit Comment"), EditCommentProc},
575 {N_("ICS Input Box"), IcsInputBoxProc},
579 MenuItem actionMenu[] = {
580 {N_("Accept"), AcceptProc},
581 {N_("Decline"), DeclineProc},
582 {N_("Rematch"), RematchProc},
583 {"----", NothingProc},
584 {N_("Call Flag"), CallFlagProc},
585 {N_("Draw"), DrawProc},
586 {N_("Adjourn"), AdjournProc},
587 {N_("Abort"), AbortProc},
588 {N_("Resign"), ResignProc},
589 {"----", NothingProc},
590 {N_("Stop Observing"), StopObservingProc},
591 {N_("Stop Examining"), StopExaminingProc},
592 {"----", NothingProc},
593 {N_("Adjudicate to White"), AdjuWhiteProc},
594 {N_("Adjudicate to Black"), AdjuBlackProc},
595 {N_("Adjudicate Draw"), AdjuDrawProc},
599 MenuItem stepMenu[] = {
600 {N_("Backward"), BackwardProc},
601 {N_("Forward"), ForwardProc},
602 {N_("Back to Start"), ToStartProc},
603 {N_("Forward to End"), ToEndProc},
604 {N_("Revert"), RevertProc},
605 {N_("Truncate Game"), TruncateGameProc},
606 {"----", NothingProc},
607 {N_("Move Now"), MoveNowProc},
608 {N_("Retract Move"), RetractMoveProc},
612 MenuItem optionsMenu[] = {
613 {N_("Flip View"), FlipViewProc},
614 {"----", NothingProc},
615 {N_("Adjudications ..."), EngineMenuProc},
616 {N_("General Settings ..."), UciMenuProc},
617 {N_("Engine #1 Settings ..."), FirstSettingsProc},
618 {N_("Engine #2 Settings ..."), SecondSettingsProc},
619 {N_("Time Control ..."), TimeControlProc},
620 {"----", NothingProc},
621 {N_("Always Queen"), AlwaysQueenProc},
622 {N_("Animate Dragging"), AnimateDraggingProc},
623 {N_("Animate Moving"), AnimateMovingProc},
624 {N_("Auto Comment"), AutocommProc},
625 {N_("Auto Flag"), AutoflagProc},
626 {N_("Auto Flip View"), AutoflipProc},
627 {N_("Auto Observe"), AutobsProc},
628 {N_("Auto Raise Board"), AutoraiseProc},
629 {N_("Auto Save"), AutosaveProc},
630 {N_("Blindfold"), BlindfoldProc},
631 {N_("Flash Moves"), FlashMovesProc},
632 {N_("Get Move List"), GetMoveListProc},
634 {N_("Highlight Dragging"), HighlightDraggingProc},
636 {N_("Highlight Last Move"), HighlightLastMoveProc},
637 {N_("Move Sound"), MoveSoundProc},
638 {N_("ICS Alarm"), IcsAlarmProc},
639 {N_("Old Save Style"), OldSaveStyleProc},
640 {N_("Periodic Updates"), PeriodicUpdatesProc},
641 {N_("Ponder Next Move"), PonderNextMoveProc},
642 {N_("Popup Exit Message"), PopupExitMessageProc},
643 {N_("Popup Move Errors"), PopupMoveErrorsProc},
644 {N_("Premove"), PremoveProc},
645 {N_("Quiet Play"), QuietPlayProc},
646 {N_("Hide Thinking"), HideThinkingProc},
647 {N_("Test Legality"), TestLegalityProc},
651 MenuItem helpMenu[] = {
652 {N_("Info XBoard"), InfoProc},
653 {N_("Man XBoard"), ManProc},
654 {"----", NothingProc},
655 {N_("Hint"), HintProc},
656 {N_("Book"), BookProc},
657 {"----", NothingProc},
662 {N_("File"), fileMenu},
663 {N_("Mode"), modeMenu},
664 {N_("Action"), actionMenu},
665 {N_("Step"), stepMenu},
666 {N_("Options"), optionsMenu},
667 {N_("Help"), helpMenu},
671 #define PAUSE_BUTTON N_("P")
672 MenuItem buttonBar[] = {
675 // {PAUSE_BUTTON, PauseProc},
681 #define PIECE_MENU_SIZE 18
682 String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
683 { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
684 N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
685 N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
686 N_("Empty square"), N_("Clear board") },
687 { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
688 N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
689 N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
690 N_("Empty square"), N_("Clear board") }
692 /* must be in same order as PieceMenuStrings! */
693 ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
694 { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
695 WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil,
696 WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0,
697 PromotePiece, DemotePiece, EmptySquare, ClearBoard },
698 { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
699 BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil,
700 BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0,
701 PromotePiece, DemotePiece, EmptySquare, ClearBoard },
704 #define DROP_MENU_SIZE 6
705 String dropMenuStrings[DROP_MENU_SIZE] = {
706 "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), N_("Queen")
708 /* must be in same order as PieceMenuStrings! */
709 ChessSquare dropMenuTranslation[DROP_MENU_SIZE] = {
710 (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
711 WhiteRook, WhiteQueen
719 DropMenuEnables dmEnables[] = {
737 { XtNborderWidth, 0 },
738 { XtNdefaultDistance, 0 },
742 { XtNborderWidth, 0 },
743 { XtNresizable, (XtArgVal) True },
747 { XtNborderWidth, 0 },
753 { XtNjustify, (XtArgVal) XtJustifyRight },
754 { XtNlabel, (XtArgVal) "..." },
755 { XtNresizable, (XtArgVal) True },
756 { XtNresize, (XtArgVal) False }
759 Arg messageArgs[] = {
760 { XtNjustify, (XtArgVal) XtJustifyLeft },
761 { XtNlabel, (XtArgVal) "..." },
762 { XtNresizable, (XtArgVal) True },
763 { XtNresize, (XtArgVal) False }
767 { XtNborderWidth, 0 },
768 { XtNjustify, (XtArgVal) XtJustifyLeft }
771 XtResource clientResources[] = {
772 { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
773 XtOffset(AppDataPtr, whitePieceColor), XtRString,
775 { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
776 XtOffset(AppDataPtr, blackPieceColor), XtRString,
778 { "lightSquareColor", "lightSquareColor", XtRString,
779 sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
780 XtRString, LIGHT_SQUARE_COLOR },
781 { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
782 XtOffset(AppDataPtr, darkSquareColor), XtRString,
784 { "highlightSquareColor", "highlightSquareColor", XtRString,
785 sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
786 XtRString, HIGHLIGHT_SQUARE_COLOR },
787 { "premoveHighlightColor", "premoveHighlightColor", XtRString,
788 sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
789 XtRString, PREMOVE_HIGHLIGHT_COLOR },
790 { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
791 XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
792 (XtPointer) MOVES_PER_SESSION },
793 { "timeIncrement", "timeIncrement", XtRInt, sizeof(int),
794 XtOffset(AppDataPtr, timeIncrement), XtRImmediate,
795 (XtPointer) TIME_INCREMENT },
796 { "initString", "initString", XtRString, sizeof(String),
797 XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
798 { "secondInitString", "secondInitString", XtRString, sizeof(String),
799 XtOffset(AppDataPtr, secondInitString), XtRString, INIT_STRING },
800 { "firstComputerString", "firstComputerString", XtRString,
801 sizeof(String), XtOffset(AppDataPtr, firstComputerString), XtRString,
803 { "secondComputerString", "secondComputerString", XtRString,
804 sizeof(String), XtOffset(AppDataPtr, secondComputerString), XtRString,
806 { "firstChessProgram", "firstChessProgram", XtRString,
807 sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
808 XtRString, FIRST_CHESS_PROGRAM },
809 { "secondChessProgram", "secondChessProgram", XtRString,
810 sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
811 XtRString, SECOND_CHESS_PROGRAM },
812 { "firstPlaysBlack", "firstPlaysBlack", XtRBoolean,
813 sizeof(Boolean), XtOffset(AppDataPtr, firstPlaysBlack),
814 XtRImmediate, (XtPointer) False },
815 { "noChessProgram", "noChessProgram", XtRBoolean,
816 sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
817 XtRImmediate, (XtPointer) False },
818 { "firstHost", "firstHost", XtRString, sizeof(String),
819 XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
820 { "secondHost", "secondHost", XtRString, sizeof(String),
821 XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
822 { "firstDirectory", "firstDirectory", XtRString, sizeof(String),
823 XtOffset(AppDataPtr, firstDirectory), XtRString, "." },
824 { "secondDirectory", "secondDirectory", XtRString, sizeof(String),
825 XtOffset(AppDataPtr, secondDirectory), XtRString, "." },
826 { "bitmapDirectory", "bitmapDirectory", XtRString,
827 sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
829 { "remoteShell", "remoteShell", XtRString, sizeof(String),
830 XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
831 { "remoteUser", "remoteUser", XtRString, sizeof(String),
832 XtOffset(AppDataPtr, remoteUser), XtRString, "" },
833 { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
834 XtOffset(AppDataPtr, timeDelay), XtRString,
835 (XtPointer) TIME_DELAY_QUOTE },
836 { "timeControl", "timeControl", XtRString, sizeof(String),
837 XtOffset(AppDataPtr, timeControl), XtRString,
838 (XtPointer) TIME_CONTROL },
839 { "internetChessServerMode", "internetChessServerMode",
840 XtRBoolean, sizeof(Boolean),
841 XtOffset(AppDataPtr, icsActive), XtRImmediate,
843 { "internetChessServerHost", "internetChessServerHost",
844 XtRString, sizeof(String),
845 XtOffset(AppDataPtr, icsHost),
846 XtRString, (XtPointer) ICS_HOST },
847 { "internetChessServerPort", "internetChessServerPort",
848 XtRString, sizeof(String),
849 XtOffset(AppDataPtr, icsPort), XtRString,
850 (XtPointer) ICS_PORT },
851 { "internetChessServerCommPort", "internetChessServerCommPort",
852 XtRString, sizeof(String),
853 XtOffset(AppDataPtr, icsCommPort), XtRString,
855 { "internetChessServerLogonScript", "internetChessServerLogonScript",
856 XtRString, sizeof(String),
857 XtOffset(AppDataPtr, icsLogon), XtRString,
859 { "internetChessServerHelper", "internetChessServerHelper",
860 XtRString, sizeof(String),
861 XtOffset(AppDataPtr, icsHelper), XtRString, "" },
862 { "internetChessServerInputBox", "internetChessServerInputBox",
863 XtRBoolean, sizeof(Boolean),
864 XtOffset(AppDataPtr, icsInputBox), XtRImmediate,
866 { "icsAlarm", "icsAlarm",
867 XtRBoolean, sizeof(Boolean),
868 XtOffset(AppDataPtr, icsAlarm), XtRImmediate,
870 { "icsAlarmTime", "icsAlarmTime",
872 XtOffset(AppDataPtr, icsAlarmTime), XtRImmediate,
874 { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
875 XtOffset(AppDataPtr, useTelnet), XtRImmediate,
877 { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
878 XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
879 { "gateway", "gateway", XtRString, sizeof(String),
880 XtOffset(AppDataPtr, gateway), XtRString, "" },
881 { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
882 XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
883 { "loadGameIndex", "loadGameIndex",
885 XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
887 { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
888 XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
889 { "autoRaiseBoard", "autoRaiseBoard", XtRBoolean,
890 sizeof(Boolean), XtOffset(AppDataPtr, autoRaiseBoard),
891 XtRImmediate, (XtPointer) True },
892 { "autoSaveGames", "autoSaveGames", XtRBoolean,
893 sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
894 XtRImmediate, (XtPointer) False },
895 { "blindfold", "blindfold", XtRBoolean,
896 sizeof(Boolean), XtOffset(AppDataPtr, blindfold),
897 XtRImmediate, (XtPointer) False },
898 { "loadPositionFile", "loadPositionFile", XtRString,
899 sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
901 { "loadPositionIndex", "loadPositionIndex",
903 XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
905 { "savePositionFile", "savePositionFile", XtRString,
906 sizeof(String), XtOffset(AppDataPtr, savePositionFile),
908 { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
909 XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
910 { "matchGames", "matchGames", XtRInt, sizeof(int),
911 XtOffset(AppDataPtr, matchGames), XtRImmediate,
913 { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
914 XtOffset(AppDataPtr, monoMode), XtRImmediate,
916 { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
917 XtOffset(AppDataPtr, debugMode), XtRImmediate,
919 { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
920 XtOffset(AppDataPtr, clockMode), XtRImmediate,
922 { "boardSize", "boardSize", XtRString, sizeof(String),
923 XtOffset(AppDataPtr, boardSize), XtRString, "" },
924 { "searchTime", "searchTime", XtRString, sizeof(String),
925 XtOffset(AppDataPtr, searchTime), XtRString,
927 { "searchDepth", "searchDepth", XtRInt, sizeof(int),
928 XtOffset(AppDataPtr, searchDepth), XtRImmediate,
930 { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
931 XtOffset(AppDataPtr, showCoords), XtRImmediate,
933 { "showJail", "showJail", XtRInt, sizeof(int),
934 XtOffset(AppDataPtr, showJail), XtRImmediate,
936 { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
937 XtOffset(AppDataPtr, showThinking), XtRImmediate,
939 { "ponderNextMove", "ponderNextMove", XtRBoolean, sizeof(Boolean),
940 XtOffset(AppDataPtr, ponderNextMove), XtRImmediate,
942 { "periodicUpdates", "periodicUpdates", XtRBoolean, sizeof(Boolean),
943 XtOffset(AppDataPtr, periodicUpdates), XtRImmediate,
945 { "clockFont", "clockFont", XtRString, sizeof(String),
946 XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
947 { "coordFont", "coordFont", XtRString, sizeof(String),
948 XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
949 { "font", "font", XtRString, sizeof(String),
950 XtOffset(AppDataPtr, font), XtRString, DEFAULT_FONT },
951 { "ringBellAfterMoves", "ringBellAfterMoves",
952 XtRBoolean, sizeof(Boolean),
953 XtOffset(AppDataPtr, ringBellAfterMoves),
954 XtRImmediate, (XtPointer) False },
955 { "autoCallFlag", "autoCallFlag", XtRBoolean,
956 sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
957 XtRImmediate, (XtPointer) False },
958 { "autoFlipView", "autoFlipView", XtRBoolean,
959 sizeof(Boolean), XtOffset(AppDataPtr, autoFlipView),
960 XtRImmediate, (XtPointer) True },
961 { "autoObserve", "autoObserve", XtRBoolean,
962 sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
963 XtRImmediate, (XtPointer) False },
964 { "autoComment", "autoComment", XtRBoolean,
965 sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
966 XtRImmediate, (XtPointer) False },
967 { "getMoveList", "getMoveList", XtRBoolean,
968 sizeof(Boolean), XtOffset(AppDataPtr, getMoveList),
969 XtRImmediate, (XtPointer) True },
971 { "highlightDragging", "highlightDragging", XtRBoolean,
972 sizeof(Boolean), XtOffset(AppDataPtr, highlightDragging),
973 XtRImmediate, (XtPointer) False },
975 { "highlightLastMove", "highlightLastMove", XtRBoolean,
976 sizeof(Boolean), XtOffset(AppDataPtr, highlightLastMove),
977 XtRImmediate, (XtPointer) False },
978 { "premove", "premove", XtRBoolean,
979 sizeof(Boolean), XtOffset(AppDataPtr, premove),
980 XtRImmediate, (XtPointer) True },
981 { "testLegality", "testLegality", XtRBoolean,
982 sizeof(Boolean), XtOffset(AppDataPtr, testLegality),
983 XtRImmediate, (XtPointer) True },
984 { "flipView", "flipView", XtRBoolean,
985 sizeof(Boolean), XtOffset(AppDataPtr, flipView),
986 XtRImmediate, (XtPointer) False },
987 { "cmail", "cmailGameName", XtRString, sizeof(String),
988 XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
989 { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
990 sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
991 XtRImmediate, (XtPointer) False },
992 { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
993 sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
994 XtRImmediate, (XtPointer) False },
995 { "quietPlay", "quietPlay", XtRBoolean,
996 sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
997 XtRImmediate, (XtPointer) False },
998 { "titleInWindow", "titleInWindow", XtRBoolean,
999 sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
1000 XtRImmediate, (XtPointer) False },
1001 { "localLineEditing", "localLineEditing", XtRBoolean,
1002 sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
1003 XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
1005 { "zippyTalk", "zippyTalk", XtRBoolean,
1006 sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
1007 XtRImmediate, (XtPointer) ZIPPY_TALK },
1008 { "zippyPlay", "zippyPlay", XtRBoolean,
1009 sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
1010 XtRImmediate, (XtPointer) ZIPPY_PLAY },
1011 { "zippyLines", "zippyLines", XtRString, sizeof(String),
1012 XtOffset(AppDataPtr, zippyLines), XtRString, ZIPPY_LINES },
1013 { "zippyPinhead", "zippyPinhead", XtRString, sizeof(String),
1014 XtOffset(AppDataPtr, zippyPinhead), XtRString, ZIPPY_PINHEAD },
1015 { "zippyPassword", "zippyPassword", XtRString, sizeof(String),
1016 XtOffset(AppDataPtr, zippyPassword), XtRString, ZIPPY_PASSWORD },
1017 { "zippyPassword2", "zippyPassword2", XtRString, sizeof(String),
1018 XtOffset(AppDataPtr, zippyPassword2), XtRString, ZIPPY_PASSWORD2 },
1019 { "zippyWrongPassword", "zippyWrongPassword", XtRString, sizeof(String),
1020 XtOffset(AppDataPtr, zippyWrongPassword), XtRString,
1021 ZIPPY_WRONG_PASSWORD },
1022 { "zippyAcceptOnly", "zippyAcceptOnly", XtRString, sizeof(String),
1023 XtOffset(AppDataPtr, zippyAcceptOnly), XtRString, ZIPPY_ACCEPT_ONLY },
1024 { "zippyUseI", "zippyUseI", XtRBoolean,
1025 sizeof(Boolean), XtOffset(AppDataPtr, zippyUseI),
1026 XtRImmediate, (XtPointer) ZIPPY_USE_I },
1027 { "zippyBughouse", "zippyBughouse", XtRInt,
1028 sizeof(int), XtOffset(AppDataPtr, zippyBughouse),
1029 XtRImmediate, (XtPointer) ZIPPY_BUGHOUSE },
1030 { "zippyNoplayCrafty", "zippyNoplayCrafty", XtRBoolean,
1031 sizeof(Boolean), XtOffset(AppDataPtr, zippyNoplayCrafty),
1032 XtRImmediate, (XtPointer) ZIPPY_NOPLAY_CRAFTY },
1033 { "zippyGameEnd", "zippyGameEnd", XtRString, sizeof(String),
1034 XtOffset(AppDataPtr, zippyGameEnd), XtRString, ZIPPY_GAME_END },
1035 { "zippyGameStart", "zippyGameStart", XtRString, sizeof(String),
1036 XtOffset(AppDataPtr, zippyGameStart), XtRString, ZIPPY_GAME_START },
1037 { "zippyAdjourn", "zippyAdjourn", XtRBoolean,
1038 sizeof(Boolean), XtOffset(AppDataPtr, zippyAdjourn),
1039 XtRImmediate, (XtPointer) ZIPPY_ADJOURN },
1040 { "zippyAbort", "zippyAbort", XtRBoolean,
1041 sizeof(Boolean), XtOffset(AppDataPtr, zippyAbort),
1042 XtRImmediate, (XtPointer) ZIPPY_ABORT },
1043 { "zippyVariants", "zippyVariants", XtRString, sizeof(String),
1044 XtOffset(AppDataPtr, zippyVariants), XtRString, ZIPPY_VARIANTS },
1045 { "zippyMaxGames", "zippyMaxGames", XtRInt, sizeof(int),
1046 XtOffset(AppDataPtr, zippyMaxGames), XtRImmediate,
1047 (XtPointer) ZIPPY_MAX_GAMES },
1048 { "zippyReplayTimeout", "zippyReplayTimeout", XtRInt, sizeof(int),
1049 XtOffset(AppDataPtr, zippyReplayTimeout), XtRImmediate,
1050 (XtPointer) ZIPPY_REPLAY_TIMEOUT },
1051 { "zippyShortGame", "zippyShortGame", XtRInt, sizeof(int),
1052 XtOffset(AppDataPtr, zippyShortGame), XtRImmediate,
1055 { "flashCount", "flashCount", XtRInt, sizeof(int),
1056 XtOffset(AppDataPtr, flashCount), XtRImmediate,
1057 (XtPointer) FLASH_COUNT },
1058 { "flashRate", "flashRate", XtRInt, sizeof(int),
1059 XtOffset(AppDataPtr, flashRate), XtRImmediate,
1060 (XtPointer) FLASH_RATE },
1061 { "pixmapDirectory", "pixmapDirectory", XtRString,
1062 sizeof(String), XtOffset(AppDataPtr, pixmapDirectory),
1064 { "msLoginDelay", "msLoginDelay", XtRInt, sizeof(int),
1065 XtOffset(AppDataPtr, msLoginDelay), XtRImmediate,
1066 (XtPointer) MS_LOGIN_DELAY },
1067 { "colorizeMessages", "colorizeMessages", XtRBoolean,
1068 sizeof(Boolean), XtOffset(AppDataPtr, colorize),
1069 XtRImmediate, (XtPointer) False },
1070 { "colorShout", "colorShout", XtRString,
1071 sizeof(String), XtOffset(AppDataPtr, colorShout),
1072 XtRString, COLOR_SHOUT },
1073 { "colorSShout", "colorSShout", XtRString,
1074 sizeof(String), XtOffset(AppDataPtr, colorSShout),
1075 XtRString, COLOR_SSHOUT },
1076 { "colorChannel1", "colorChannel1", XtRString,
1077 sizeof(String), XtOffset(AppDataPtr, colorChannel1),
1078 XtRString, COLOR_CHANNEL1 },
1079 { "colorChannel", "colorChannel", XtRString,
1080 sizeof(String), XtOffset(AppDataPtr, colorChannel),
1081 XtRString, COLOR_CHANNEL },
1082 { "colorKibitz", "colorKibitz", XtRString,
1083 sizeof(String), XtOffset(AppDataPtr, colorKibitz),
1084 XtRString, COLOR_KIBITZ },
1085 { "colorTell", "colorTell", XtRString,
1086 sizeof(String), XtOffset(AppDataPtr, colorTell),
1087 XtRString, COLOR_TELL },
1088 { "colorChallenge", "colorChallenge", XtRString,
1089 sizeof(String), XtOffset(AppDataPtr, colorChallenge),
1090 XtRString, COLOR_CHALLENGE },
1091 { "colorRequest", "colorRequest", XtRString,
1092 sizeof(String), XtOffset(AppDataPtr, colorRequest),
1093 XtRString, COLOR_REQUEST },
1094 { "colorSeek", "colorSeek", XtRString,
1095 sizeof(String), XtOffset(AppDataPtr, colorSeek),
1096 XtRString, COLOR_SEEK },
1097 { "colorNormal", "colorNormal", XtRString,
1098 sizeof(String), XtOffset(AppDataPtr, colorNormal),
1099 XtRString, COLOR_NORMAL },
1100 { "soundProgram", "soundProgram", XtRString,
1101 sizeof(String), XtOffset(AppDataPtr, soundProgram),
1102 XtRString, "play" },
1103 { "soundShout", "soundShout", XtRString,
1104 sizeof(String), XtOffset(AppDataPtr, soundShout),
1106 { "soundSShout", "soundSShout", XtRString,
1107 sizeof(String), XtOffset(AppDataPtr, soundSShout),
1109 { "soundChannel1", "soundChannel1", XtRString,
1110 sizeof(String), XtOffset(AppDataPtr, soundChannel1),
1112 { "soundChannel", "soundChannel", XtRString,
1113 sizeof(String), XtOffset(AppDataPtr, soundChannel),
1115 { "soundKibitz", "soundKibitz", XtRString,
1116 sizeof(String), XtOffset(AppDataPtr, soundKibitz),
1118 { "soundTell", "soundTell", XtRString,
1119 sizeof(String), XtOffset(AppDataPtr, soundTell),
1121 { "soundChallenge", "soundChallenge", XtRString,
1122 sizeof(String), XtOffset(AppDataPtr, soundChallenge),
1124 { "soundRequest", "soundRequest", XtRString,
1125 sizeof(String), XtOffset(AppDataPtr, soundRequest),
1127 { "soundSeek", "soundSeek", XtRString,
1128 sizeof(String), XtOffset(AppDataPtr, soundSeek),
1130 { "soundMove", "soundMove", XtRString,
1131 sizeof(String), XtOffset(AppDataPtr, soundMove),
1133 { "soundIcsWin", "soundIcsWin", XtRString,
1134 sizeof(String), XtOffset(AppDataPtr, soundIcsWin),
1136 { "soundIcsLoss", "soundIcsLoss", XtRString,
1137 sizeof(String), XtOffset(AppDataPtr, soundIcsLoss),
1139 { "soundIcsDraw", "soundIcsDraw", XtRString,
1140 sizeof(String), XtOffset(AppDataPtr, soundIcsDraw),
1142 { "soundIcsUnfinished", "soundIcsUnfinished", XtRString,
1143 sizeof(String), XtOffset(AppDataPtr, soundIcsUnfinished),
1145 { "soundIcsAlarm", "soundIcsAlarm", XtRString,
1146 sizeof(String), XtOffset(AppDataPtr, soundIcsAlarm),
1148 { "reuseFirst", "reuseFirst", XtRBoolean,
1149 sizeof(Boolean), XtOffset(AppDataPtr, reuseFirst),
1150 XtRImmediate, (XtPointer) True },
1151 { "reuseSecond", "reuseSecond", XtRBoolean,
1152 sizeof(Boolean), XtOffset(AppDataPtr, reuseSecond),
1153 XtRImmediate, (XtPointer) True },
1154 { "animateDragging", "animateDragging", XtRBoolean,
1155 sizeof(Boolean), XtOffset(AppDataPtr, animateDragging),
1156 XtRImmediate, (XtPointer) True },
1157 { "animateMoving", "animateMoving", XtRBoolean,
1158 sizeof(Boolean), XtOffset(AppDataPtr, animate),
1159 XtRImmediate, (XtPointer) True },
1160 { "animateSpeed", "animateSpeed", XtRInt,
1161 sizeof(int), XtOffset(AppDataPtr, animSpeed),
1162 XtRImmediate, (XtPointer)10 },
1163 { "popupExitMessage", "popupExitMessage", XtRBoolean,
1164 sizeof(Boolean), XtOffset(AppDataPtr, popupExitMessage),
1165 XtRImmediate, (XtPointer) True },
1166 { "popupMoveErrors", "popupMoveErrors", XtRBoolean,
1167 sizeof(Boolean), XtOffset(AppDataPtr, popupMoveErrors),
1168 XtRImmediate, (XtPointer) False },
1169 { "fontSizeTolerance", "fontSizeTolerance", XtRInt,
1170 sizeof(int), XtOffset(AppDataPtr, fontSizeTolerance),
1171 XtRImmediate, (XtPointer)4 },
1172 { "initialMode", "initialMode", XtRString,
1173 sizeof(String), XtOffset(AppDataPtr, initialMode),
1174 XtRImmediate, (XtPointer) "" },
1175 { "variant", "variant", XtRString,
1176 sizeof(String), XtOffset(AppDataPtr, variant),
1177 XtRImmediate, (XtPointer) "normal" },
1178 { "firstProtocolVersion", "firstProtocolVersion", XtRInt,
1179 sizeof(int), XtOffset(AppDataPtr, firstProtocolVersion),
1180 XtRImmediate, (XtPointer)PROTOVER },
1181 { "secondProtocolVersion", "secondProtocolVersion", XtRInt,
1182 sizeof(int), XtOffset(AppDataPtr, secondProtocolVersion),
1183 XtRImmediate, (XtPointer)PROTOVER },
1184 { "showButtonBar", "showButtonBar", XtRBoolean,
1185 sizeof(Boolean), XtOffset(AppDataPtr, showButtonBar),
1186 XtRImmediate, (XtPointer) True },
1187 { "lowTimeWarningColor", "lowTimeWarningColor", XtRString,
1188 sizeof(String), XtOffset(AppDataPtr, lowTimeWarningColor),
1189 XtRString, COLOR_LOWTIMEWARNING },
1190 { "lowTimeWarning", "lowTimeWarning", XtRBoolean,
1191 sizeof(Boolean), XtOffset(AppDataPtr, lowTimeWarning),
1192 XtRImmediate, (XtPointer) False },
1193 {"icsEngineAnalyze", "icsEngineAnalyze", XtRBoolean, /* [DM] icsEngineAnalyze */
1194 sizeof(Boolean), XtOffset(AppDataPtr, icsEngineAnalyze),
1195 XtRImmediate, (XtPointer) False },
1196 { "firstScoreAbs", "firstScoreAbs", XtRBoolean,
1197 sizeof(Boolean), XtOffset(AppDataPtr, firstScoreIsAbsolute),
1198 XtRImmediate, (XtPointer) False },
1199 { "secondScoreAbs", "secondScoreAbs", XtRBoolean,
1200 sizeof(Boolean), XtOffset(AppDataPtr, secondScoreIsAbsolute),
1201 XtRImmediate, (XtPointer) False },
1202 { "pgnExtendedInfo", "pgnExtendedInfo", XtRBoolean,
1203 sizeof(Boolean), XtOffset(AppDataPtr, saveExtendedInfoInPGN),
1204 XtRImmediate, (XtPointer) False },
1205 { "hideThinkingFromHuman", "hideThinkingFromHuman", XtRBoolean,
1206 sizeof(Boolean), XtOffset(AppDataPtr, hideThinkingFromHuman),
1207 XtRImmediate, (XtPointer) True },
1208 { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
1209 sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
1210 XtRImmediate, (XtPointer) 0},
1211 { "pgnEventHeader", "pgnEventHeader", XtRString,
1212 sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
1213 XtRImmediate, (XtPointer) "Computer Chess Game" },
1214 { "defaultFrcPosition", "defaultFrcPositon", XtRInt,
1215 sizeof(int), XtOffset(AppDataPtr, defaultFrcPosition),
1216 XtRImmediate, (XtPointer) -1},
1217 { "gameListTags", "gameListTags", XtRString,
1218 sizeof(String), XtOffset(AppDataPtr, gameListTags),
1219 XtRImmediate, (XtPointer) GLT_DEFAULT_TAGS },
1221 // [HGM] 4.3.xx options
1222 { "boardWidth", "boardWidth", XtRInt,
1223 sizeof(int), XtOffset(AppDataPtr, NrFiles),
1224 XtRImmediate, (XtPointer) -1},
1225 { "boardHeight", "boardHeight", XtRInt,
1226 sizeof(int), XtOffset(AppDataPtr, NrRanks),
1227 XtRImmediate, (XtPointer) -1},
1228 { "matchPause", "matchPause", XtRInt,
1229 sizeof(int), XtOffset(AppDataPtr, matchPause),
1230 XtRImmediate, (XtPointer) 10000},
1231 { "holdingsSize", "holdingsSize", XtRInt,
1232 sizeof(int), XtOffset(AppDataPtr, holdingsSize),
1233 XtRImmediate, (XtPointer) -1},
1234 { "flipBlack", "flipBlack", XtRBoolean,
1235 sizeof(Boolean), XtOffset(AppDataPtr, upsideDown),
1236 XtRImmediate, (XtPointer) False},
1237 { "allWhite", "allWhite", XtRBoolean,
1238 sizeof(Boolean), XtOffset(AppDataPtr, allWhite),
1239 XtRImmediate, (XtPointer) False},
1240 { "pieceToCharTable", "pieceToCharTable", XtRString,
1241 sizeof(String), XtOffset(AppDataPtr, pieceToCharTable),
1242 XtRImmediate, (XtPointer) 0},
1243 { "alphaRank", "alphaRank", XtRBoolean,
1244 sizeof(Boolean), XtOffset(AppDataPtr, alphaRank),
1245 XtRImmediate, (XtPointer) False},
1246 { "testClaims", "testClaims", XtRBoolean,
1247 sizeof(Boolean), XtOffset(AppDataPtr, testClaims),
1248 XtRImmediate, (XtPointer) True},
1249 { "checkMates", "checkMates", XtRBoolean,
1250 sizeof(Boolean), XtOffset(AppDataPtr, checkMates),
1251 XtRImmediate, (XtPointer) True},
1252 { "materialDraws", "materialDraws", XtRBoolean,
1253 sizeof(Boolean), XtOffset(AppDataPtr, materialDraws),
1254 XtRImmediate, (XtPointer) True},
1255 { "trivialDraws", "trivialDraws", XtRBoolean,
1256 sizeof(Boolean), XtOffset(AppDataPtr, trivialDraws),
1257 XtRImmediate, (XtPointer) False},
1258 { "ruleMoves", "ruleMoves", XtRInt,
1259 sizeof(int), XtOffset(AppDataPtr, ruleMoves),
1260 XtRImmediate, (XtPointer) 51},
1261 { "repeatsToDraw", "repeatsToDraw", XtRInt,
1262 sizeof(int), XtOffset(AppDataPtr, drawRepeats),
1263 XtRImmediate, (XtPointer) 6},
1264 { "engineDebugOutput", "engineDebugOutput", XtRInt,
1265 sizeof(int), XtOffset(AppDataPtr, engineComments),
1266 XtRImmediate, (XtPointer) 1},
1267 { "userName", "userName", XtRString,
1268 sizeof(int), XtOffset(AppDataPtr, userName),
1269 XtRImmediate, (XtPointer) 0},
1270 { "autoKibitz", "autoKibitz", XtRBoolean,
1271 sizeof(Boolean), XtOffset(AppDataPtr, autoKibitz),
1272 XtRImmediate, (XtPointer) False},
1273 { "firstTimeOdds", "firstTimeOdds", XtRInt,
1274 sizeof(int), XtOffset(AppDataPtr, firstTimeOdds),
1275 XtRImmediate, (XtPointer) 1},
1276 { "secondTimeOdds", "secondTimeOdds", XtRInt,
1277 sizeof(int), XtOffset(AppDataPtr, secondTimeOdds),
1278 XtRImmediate, (XtPointer) 1},
1279 { "timeOddsMode", "timeOddsMode", XtRInt,
1280 sizeof(int), XtOffset(AppDataPtr, timeOddsMode),
1281 XtRImmediate, (XtPointer) 0},
1282 { "firstAccumulateTC", "firstAccumulateTC", XtRInt,
1283 sizeof(int), XtOffset(AppDataPtr, firstAccumulateTC),
1284 XtRImmediate, (XtPointer) 1},
1285 { "secondAccumulateTC", "secondAccumulateTC", XtRInt,
1286 sizeof(int), XtOffset(AppDataPtr, secondAccumulateTC),
1287 XtRImmediate, (XtPointer) 1},
1288 { "firstNPS", "firstNPS", XtRInt,
1289 sizeof(int), XtOffset(AppDataPtr, firstNPS),
1290 XtRImmediate, (XtPointer) -1},
1291 { "secondNPS", "secondNPS", XtRInt,
1292 sizeof(int), XtOffset(AppDataPtr, secondNPS),
1293 XtRImmediate, (XtPointer) -1},
1294 { "serverMoves", "serverMoves", XtRString,
1295 sizeof(String), XtOffset(AppDataPtr, serverMovesName),
1296 XtRImmediate, (XtPointer) 0},
1297 { "serverPause", "serverPause", XtRInt,
1298 sizeof(int), XtOffset(AppDataPtr, serverPause),
1299 XtRImmediate, (XtPointer) 0},
1300 { "suppressLoadMoves", "suppressLoadMoves", XtRBoolean,
1301 sizeof(Boolean), XtOffset(AppDataPtr, suppressLoadMoves),
1302 XtRImmediate, (XtPointer) False},
1303 { "userName", "userName", XtRString,
1304 sizeof(String), XtOffset(AppDataPtr, userName),
1305 XtRImmediate, (XtPointer) 0},
1306 { "egtFormats", "egtFormats", XtRString,
1307 sizeof(String), XtOffset(AppDataPtr, egtFormats),
1308 XtRImmediate, (XtPointer) 0},
1309 { "rewindIndex", "rewindIndex", XtRInt,
1310 sizeof(int), XtOffset(AppDataPtr, rewindIndex),
1311 XtRImmediate, (XtPointer) 0},
1312 { "sameColorGames", "sameColorGames", XtRInt,
1313 sizeof(int), XtOffset(AppDataPtr, sameColorGames),
1314 XtRImmediate, (XtPointer) 0},
1315 { "smpCores", "smpCores", XtRInt,
1316 sizeof(int), XtOffset(AppDataPtr, smpCores),
1317 XtRImmediate, (XtPointer) 1},
1318 { "niceEngines", "niceEngines", XtRInt,
1319 sizeof(int), XtOffset(AppDataPtr, niceEngines),
1320 XtRImmediate, (XtPointer) 0},
1321 { "nameOfDebugFile", "nameOfDebugFile", XtRString,
1322 sizeof(String), XtOffset(AppDataPtr, nameOfDebugFile),
1323 XtRImmediate, (XtPointer) "xboard.debug"},
1324 { "engineDebugOutput", "engineDebugOutput", XtRInt,
1325 sizeof(int), XtOffset(AppDataPtr, engineComments),
1326 XtRImmediate, (XtPointer) 0},
1327 { "noGUI", "noGUI", XtRBoolean,
1328 sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
1329 XtRImmediate, (XtPointer) 0},
1330 { "firstOptions", "firstOptions", XtRString,
1331 sizeof(String), XtOffset(AppDataPtr, firstOptions),
1332 XtRImmediate, (XtPointer) "" },
1333 { "secondOptions", "secondOptions", XtRString,
1334 sizeof(String), XtOffset(AppDataPtr, secondOptions),
1335 XtRImmediate, (XtPointer) "" },
1336 { "firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XtRString,
1337 sizeof(String), XtOffset(AppDataPtr, fenOverride1),
1338 XtRImmediate, (XtPointer) 0 },
1339 { "secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XtRString,
1340 sizeof(String), XtOffset(AppDataPtr, fenOverride2),
1341 XtRImmediate, (XtPointer) 0 },
1343 // [HGM] Winboard_x UCI options
1344 { "firstIsUCI", "firstIsUCI", XtRBoolean,
1345 sizeof(Boolean), XtOffset(AppDataPtr, firstIsUCI),
1346 XtRImmediate, (XtPointer) False},
1347 { "secondIsUCI", "secondIsUCI", XtRBoolean,
1348 sizeof(Boolean), XtOffset(AppDataPtr, secondIsUCI),
1349 XtRImmediate, (XtPointer) False},
1350 { "firstHasOwnBookUCI", "firstHasOwnBookUCI", XtRBoolean,
1351 sizeof(Boolean), XtOffset(AppDataPtr, firstHasOwnBookUCI),
1352 XtRImmediate, (XtPointer) True},
1353 { "secondHasOwnBookUCI", "secondHasOwnBookUCI", XtRBoolean,
1354 sizeof(Boolean), XtOffset(AppDataPtr, secondHasOwnBookUCI),
1355 XtRImmediate, (XtPointer) True},
1356 { "usePolyglotBook", "usePolyglotBook", XtRBoolean,
1357 sizeof(Boolean), XtOffset(AppDataPtr, usePolyglotBook),
1358 XtRImmediate, (XtPointer) False},
1359 { "defaultHashSize", "defaultHashSize", XtRInt,
1360 sizeof(int), XtOffset(AppDataPtr, defaultHashSize),
1361 XtRImmediate, (XtPointer) 64},
1362 { "defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XtRInt,
1363 sizeof(int), XtOffset(AppDataPtr, defaultCacheSizeEGTB),
1364 XtRImmediate, (XtPointer) 4},
1365 { "polyglotDir", "polyglotDir", XtRString,
1366 sizeof(String), XtOffset(AppDataPtr, polyglotDir),
1367 XtRImmediate, (XtPointer) "." },
1368 { "polyglotBook", "polyglotBook", XtRString,
1369 sizeof(String), XtOffset(AppDataPtr, polyglotBook),
1370 XtRImmediate, (XtPointer) "" },
1371 { "defaultPathEGTB", "defaultPathEGTB", XtRString,
1372 sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),
1373 XtRImmediate, (XtPointer) "/usr/local/share/egtb"},
1374 { "delayBeforeQuit", "delayBeforeQuit", XtRInt,
1375 sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),
1376 XtRImmediate, (XtPointer) 0},
1377 { "delayAfterQuit", "delayAfterQuit", XtRInt,
1378 sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
1379 XtRImmediate, (XtPointer) 0},
1382 XrmOptionDescRec shellOptions[] = {
1383 { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
1384 { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
1385 { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
1386 { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
1387 { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
1388 { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
1389 { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
1390 { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
1391 { "-timeIncrement", "timeIncrement", XrmoptionSepArg, NULL },
1392 { "-inc", "timeIncrement", XrmoptionSepArg, NULL },
1393 { "-initString", "initString", XrmoptionSepArg, NULL },
1394 { "-firstInitString", "initString", XrmoptionSepArg, NULL },
1395 { "-secondInitString", "secondInitString", XrmoptionSepArg, NULL },
1396 { "-firstComputerString", "firstComputerString", XrmoptionSepArg, NULL },
1397 { "-secondComputerString", "secondComputerString", XrmoptionSepArg, NULL },
1398 { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
1399 { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
1400 { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
1401 { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
1402 { "-firstPlaysBlack", "firstPlaysBlack", XrmoptionSepArg, NULL },
1403 { "-fb", "firstPlaysBlack", XrmoptionNoArg, "True" },
1404 { "-xfb", "firstPlaysBlack", XrmoptionNoArg, "False" },
1405 { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
1406 { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
1407 { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
1408 { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
1409 { "-fh", "firstHost", XrmoptionSepArg, NULL },
1410 { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
1411 { "-sh", "secondHost", XrmoptionSepArg, NULL },
1412 { "-firstDirectory", "firstDirectory", XrmoptionSepArg, NULL },
1413 { "-fd", "firstDirectory", XrmoptionSepArg, NULL },
1414 { "-secondDirectory", "secondDirectory", XrmoptionSepArg, NULL },
1415 { "-sd", "secondDirectory", XrmoptionSepArg, NULL },
1416 { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
1417 { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
1418 { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
1419 { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
1420 { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
1421 { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
1422 { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
1423 { "-td", "timeDelay", XrmoptionSepArg, NULL },
1424 { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
1425 { "-tc", "timeControl", XrmoptionSepArg, NULL },
1426 { "-internetChessServerMode", "internetChessServerMode",
1427 XrmoptionSepArg, NULL },
1428 { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
1429 { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
1430 { "-internetChessServerHost", "internetChessServerHost",
1431 XrmoptionSepArg, NULL },
1432 { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
1433 { "-internetChessServerPort", "internetChessServerPort",
1434 XrmoptionSepArg, NULL },
1435 { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
1436 { "-internetChessServerCommPort", "internetChessServerCommPort",
1437 XrmoptionSepArg, NULL },
1438 { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
1439 { "-internetChessServerLogonScript", "internetChessServerLogonScript",
1440 XrmoptionSepArg, NULL },
1441 { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
1442 { "-internetChessServerHelper", "internetChessServerHelper",
1443 XrmoptionSepArg, NULL },
1444 { "-icshelper", "internetChessServerHelper", XrmoptionSepArg, NULL },
1445 { "-internetChessServerInputBox", "internetChessServerInputBox",
1446 XrmoptionSepArg, NULL },
1447 { "-icsinput", "internetChessServerInputBox", XrmoptionNoArg, "True" },
1448 { "-xicsinput", "internetChessServerInputBox", XrmoptionNoArg, "False" },
1449 { "-icsAlarm", "icsAlarm", XrmoptionSepArg, NULL },
1450 { "-alarm", "icsAlarm", XrmoptionNoArg, "True" },
1451 { "-xalarm", "icsAlarm", XrmoptionNoArg, "False" },
1452 { "-icsAlarmTime", "icsAlarmTime", XrmoptionSepArg, NULL },
1453 { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
1454 { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
1455 { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
1456 { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
1457 { "-gateway", "gateway", XrmoptionSepArg, NULL },
1458 { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
1459 { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
1460 { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
1461 { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
1462 { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
1463 { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
1464 { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
1465 { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
1466 { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
1467 { "-autoRaiseBoard", "autoRaiseBoard", XrmoptionSepArg, NULL },
1468 { "-autoraise", "autoRaiseBoard", XrmoptionNoArg, "True" },
1469 { "-xautoraise", "autoRaiseBoard", XrmoptionNoArg, "False" },
1470 { "-blindfold", "blindfold", XrmoptionSepArg, NULL },
1471 { "-blind", "blindfold", XrmoptionNoArg, "True" },
1472 { "-xblind", "blindfold", XrmoptionNoArg, "False" },
1473 { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
1474 { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
1475 { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
1476 { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
1477 { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
1478 { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
1479 { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
1480 { "-mm", "matchMode", XrmoptionNoArg, "True" },
1481 { "-xmm", "matchMode", XrmoptionNoArg, "False" },
1482 { "-matchGames", "matchGames", XrmoptionSepArg, NULL },
1483 { "-mg", "matchGames", XrmoptionSepArg, NULL },
1484 { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
1485 { "-mono", "monoMode", XrmoptionNoArg, "True" },
1486 { "-xmono", "monoMode", XrmoptionNoArg, "False" },
1487 { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
1488 { "-debug", "debugMode", XrmoptionNoArg, "True" },
1489 { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
1490 { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
1491 { "-clock", "clockMode", XrmoptionNoArg, "True" },
1492 { "-xclock", "clockMode", XrmoptionNoArg, "False" },
1493 { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
1494 { "-size", "boardSize", XrmoptionSepArg, NULL },
1495 { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
1496 { "-st", "searchTime", XrmoptionSepArg, NULL },
1497 { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
1498 { "-depth", "searchDepth", XrmoptionSepArg, NULL },
1499 { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
1500 { "-coords", "showCoords", XrmoptionNoArg, "True" },
1501 { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
1503 { "-showJail", "showJail", XrmoptionSepArg, NULL },
1504 { "-jail", "showJail", XrmoptionNoArg, "1" },
1505 { "-sidejail", "showJail", XrmoptionNoArg, "2" },
1506 { "-xjail", "showJail", XrmoptionNoArg, "0" },
1508 { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
1509 { "-thinking", "showThinking", XrmoptionNoArg, "True" },
1510 { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
1511 { "-ponderNextMove", "ponderNextMove", XrmoptionSepArg, NULL },
1512 { "-ponder", "ponderNextMove", XrmoptionNoArg, "True" },
1513 { "-xponder", "ponderNextMove", XrmoptionNoArg, "False" },
1514 { "-periodicUpdates", "periodicUpdates", XrmoptionSepArg, NULL },
1515 { "-periodic", "periodicUpdates", XrmoptionNoArg, "True" },
1516 { "-xperiodic", "periodicUpdates", XrmoptionNoArg, "False" },
1517 { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
1518 { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
1519 { "-font", "font", XrmoptionSepArg, NULL },
1520 { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
1521 { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1522 { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1523 { "-movesound", "ringBellAfterMoves", XrmoptionNoArg, "True" },
1524 { "-xmovesound", "ringBellAfterMoves", XrmoptionNoArg, "False" },
1525 { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
1526 { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
1527 { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
1528 { "-autoFlipView", "autoFlipView", XrmoptionSepArg, NULL },
1529 { "-autoflip", "autoFlipView", XrmoptionNoArg, "True" },
1530 { "-xautoflip", "autoFlipView", XrmoptionNoArg, "False" },
1531 { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
1532 { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
1533 { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
1534 { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
1535 { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
1536 { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
1537 { "-getMoveList", "getMoveList", XrmoptionSepArg, NULL },
1538 { "-moves", "getMoveList", XrmoptionNoArg, "True" },
1539 { "-xmoves", "getMoveList", XrmoptionNoArg, "False" },
1541 { "-highlightDragging", "highlightDragging", XrmoptionSepArg, NULL },
1542 { "-highdrag", "highlightDragging", XrmoptionNoArg, "True" },
1543 { "-xhighdrag", "highlightDragging", XrmoptionNoArg, "False" },
1545 { "-highlightLastMove", "highlightLastMove", XrmoptionSepArg, NULL },
1546 { "-highlight", "highlightLastMove", XrmoptionNoArg, "True" },
1547 { "-xhighlight", "highlightLastMove", XrmoptionNoArg, "False" },
1548 { "-premove", "premove", XrmoptionSepArg, NULL },
1549 { "-pre", "premove", XrmoptionNoArg, "True" },
1550 { "-xpre", "premove", XrmoptionNoArg, "False" },
1551 { "-testLegality", "testLegality", XrmoptionSepArg, NULL },
1552 { "-legal", "testLegality", XrmoptionNoArg, "True" },
1553 { "-xlegal", "testLegality", XrmoptionNoArg, "False" },
1554 { "-flipView", "flipView", XrmoptionSepArg, NULL },
1555 { "-flip", "flipView", XrmoptionNoArg, "True" },
1556 { "-xflip", "flipView", XrmoptionNoArg, "False" },
1557 { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
1558 { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
1559 XrmoptionSepArg, NULL },
1560 { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
1561 { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
1562 { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
1563 { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
1564 { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
1565 { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
1566 { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
1567 { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
1568 { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
1569 { "-title", "titleInWindow", XrmoptionNoArg, "True" },
1570 { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
1572 { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
1573 { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
1574 { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
1575 { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
1576 { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
1577 { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
1578 { "-zippyLines", "zippyLines", XrmoptionSepArg, NULL },
1579 { "-zippyPinhead", "zippyPinhead", XrmoptionSepArg, NULL },
1580 { "-zippyPassword", "zippyPassword", XrmoptionSepArg, NULL },
1581 { "-zippyPassword2", "zippyPassword2", XrmoptionSepArg, NULL },
1582 { "-zippyWrongPassword", "zippyWrongPassword", XrmoptionSepArg, NULL },
1583 { "-zippyAcceptOnly", "zippyAcceptOnly", XrmoptionSepArg, NULL },
1584 { "-zippyUseI", "zippyUseI", XrmoptionSepArg, NULL },
1585 { "-zui", "zippyUseI", XrmoptionNoArg, "True" },
1586 { "-xzui", "zippyUseI", XrmoptionNoArg, "False" },
1587 { "-zippyBughouse", "zippyBughouse", XrmoptionSepArg, NULL },
1588 { "-zippyNoplayCrafty", "zippyNoplayCrafty", XrmoptionSepArg, NULL },
1589 { "-znc", "zippyNoplayCrafty", XrmoptionNoArg, "True" },
1590 { "-xznc", "zippyNoplayCrafty", XrmoptionNoArg, "False" },
1591 { "-zippyGameEnd", "zippyGameEnd", XrmoptionSepArg, NULL },
1592 { "-zippyGameStart", "zippyGameStart", XrmoptionSepArg, NULL },
1593 { "-zippyAdjourn", "zippyAdjourn", XrmoptionSepArg, NULL },
1594 { "-zadj", "zippyAdjourn", XrmoptionNoArg, "True" },
1595 { "-xzadj", "zippyAdjourn", XrmoptionNoArg, "False" },
1596 { "-zippyAbort", "zippyAbort", XrmoptionSepArg, NULL },
1597 { "-zab", "zippyAbort", XrmoptionNoArg, "True" },
1598 { "-xzab", "zippyAbort", XrmoptionNoArg, "False" },
1599 { "-zippyVariants", "zippyVariants", XrmoptionSepArg, NULL },
1600 { "-zippyMaxGames", "zippyMaxGames", XrmoptionSepArg, NULL },
1601 { "-zippyReplayTimeout", "zippyReplayTimeout", XrmoptionSepArg, NULL },
1602 { "-zippyShortGame", "zippyShortGame", XrmoptionSepArg, NULL },
1604 { "-flashCount", "flashCount", XrmoptionSepArg, NULL },
1605 { "-flash", "flashCount", XrmoptionNoArg, "3" },
1606 { "-xflash", "flashCount", XrmoptionNoArg, "0" },
1607 { "-flashRate", "flashRate", XrmoptionSepArg, NULL },
1608 { "-pixmapDirectory", "pixmapDirectory", XrmoptionSepArg, NULL },
1609 { "-msLoginDelay", "msLoginDelay", XrmoptionSepArg, NULL },
1610 { "-pixmap", "pixmapDirectory", XrmoptionSepArg, NULL },
1611 { "-colorizeMessages", "colorizeMessages", XrmoptionSepArg, NULL },
1612 { "-colorize", "colorizeMessages", XrmoptionNoArg, "True" },
1613 { "-xcolorize", "colorizeMessages", XrmoptionNoArg, "False" },
1614 { "-colorShout", "colorShout", XrmoptionSepArg, NULL },
1615 { "-colorSShout", "colorSShout", XrmoptionSepArg, NULL },
1616 { "-colorCShout", "colorSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1617 { "-colorChannel1", "colorChannel1", XrmoptionSepArg, NULL },
1618 { "-colorChannel", "colorChannel", XrmoptionSepArg, NULL },
1619 { "-colorKibitz", "colorKibitz", XrmoptionSepArg, NULL },
1620 { "-colorTell", "colorTell", XrmoptionSepArg, NULL },
1621 { "-colorChallenge", "colorChallenge", XrmoptionSepArg, NULL },
1622 { "-colorRequest", "colorRequest", XrmoptionSepArg, NULL },
1623 { "-colorSeek", "colorSeek", XrmoptionSepArg, NULL },
1624 { "-colorNormal", "colorNormal", XrmoptionSepArg, NULL },
1625 { "-soundProgram", "soundProgram", XrmoptionSepArg, NULL },
1626 { "-soundShout", "soundShout", XrmoptionSepArg, NULL },
1627 { "-soundSShout", "soundSShout", XrmoptionSepArg, NULL },
1628 { "-soundCShout", "soundSShout", XrmoptionSepArg, NULL }, /*FICS name*/
1629 { "-soundChannel1", "soundChannel1", XrmoptionSepArg, NULL },
1630 { "-soundChannel", "soundChannel", XrmoptionSepArg, NULL },
1631 { "-soundKibitz", "soundKibitz", XrmoptionSepArg, NULL },
1632 { "-soundTell", "soundTell", XrmoptionSepArg, NULL },
1633 { "-soundChallenge", "soundChallenge", XrmoptionSepArg, NULL },
1634 { "-soundRequest", "soundRequest", XrmoptionSepArg, NULL },
1635 { "-soundSeek", "soundSeek", XrmoptionSepArg, NULL },
1636 { "-soundMove", "soundMove", XrmoptionSepArg, NULL },
1637 { "-soundIcsWin", "soundIcsWin", XrmoptionSepArg, NULL },
1638 { "-soundIcsLoss", "soundIcsLoss", XrmoptionSepArg, NULL },
1639 { "-soundIcsDraw", "soundIcsDraw", XrmoptionSepArg, NULL },
1640 { "-soundIcsUnfinished", "soundIcsUnfinished", XrmoptionSepArg, NULL },
1641 { "-soundIcsAlarm", "soundIcsAlarm", XrmoptionSepArg, NULL },
1642 { "-reuseFirst", "reuseFirst", XrmoptionSepArg, NULL },
1643 { "-reuseChessPrograms", "reuseFirst", XrmoptionSepArg, NULL }, /*compat*/
1644 { "-reuse", "reuseFirst", XrmoptionNoArg, "True" },
1645 { "-xreuse", "reuseFirst", XrmoptionNoArg, "False" },
1646 { "-reuseSecond", "reuseSecond", XrmoptionSepArg, NULL },
1647 { "-reuse2", "reuseSecond", XrmoptionNoArg, "True" },
1648 { "-xreuse2", "reuseSecond", XrmoptionNoArg, "False" },
1649 { "-animateMoving", "animateMoving", XrmoptionSepArg, NULL },
1650 { "-animate", "animateMoving", XrmoptionNoArg, "True" },
1651 { "-xanimate", "animateMoving", XrmoptionNoArg, "False" },
1652 { "-animateDragging", "animateDragging", XrmoptionSepArg, NULL },
1653 { "-drag", "animateDragging", XrmoptionNoArg, "True" },
1654 { "-xdrag", "animateDragging", XrmoptionNoArg, "False" },
1655 { "-animateSpeed", "animateSpeed", XrmoptionSepArg, NULL },
1656 { "-popupExitMessage", "popupExitMessage", XrmoptionSepArg, NULL },
1657 { "-exit", "popupExitMessage", XrmoptionNoArg, "True" },
1658 { "-xexit", "popupExitMessage", XrmoptionNoArg, "False" },
1659 { "-popupMoveErrors", "popupMoveErrors", XrmoptionSepArg, NULL },
1660 { "-popup", "popupMoveErrors", XrmoptionNoArg, "True" },
1661 { "-xpopup", "popupMoveErrors", XrmoptionNoArg, "False" },
1662 { "-fontSizeTolerance", "fontSizeTolerance", XrmoptionSepArg, NULL },
1663 { "-initialMode", "initialMode", XrmoptionSepArg, NULL },
1664 { "-mode", "initialMode", XrmoptionSepArg, NULL },
1665 { "-variant", "variant", XrmoptionSepArg, NULL },
1666 { "-firstProtocolVersion", "firstProtocolVersion", XrmoptionSepArg, NULL },
1667 { "-secondProtocolVersion","secondProtocolVersion",XrmoptionSepArg, NULL },
1668 { "-showButtonBar", "showButtonBar", XrmoptionSepArg, NULL },
1669 { "-buttons", "showButtonBar", XrmoptionNoArg, "True" },
1670 { "-xbuttons", "showButtonBar", XrmoptionNoArg, "False" },
1671 { "-lowTimeWarningColor", "lowTimeWarningColor", XrmoptionSepArg, NULL },
1672 { "-lowTimeWarning", "lowTimeWarning", XrmoptionSepArg, NULL },
1673 /* [AS,HR] New features */
1674 { "-firstScoreAbs", "firstScoreAbs", XrmoptionSepArg, NULL },
1675 { "-secondScoreAbs", "secondScoreAbs", XrmoptionSepArg, NULL },
1676 { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
1677 { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
1678 { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
1679 { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
1680 { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
1681 { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
1682 { "-fUCI", "firstIsUCI", XrmoptionNoArg, "True" },
1683 { "-sUCI", "secondIsUCI", XrmoptionNoArg, "True" },
1684 { "-firstHasOwnBookUCI", "firstHasOwnBookUCI", XrmoptionSepArg, NULL },
1685 { "-secondHasOwnBookUCI", "secondHasOwnBookUCI", XrmoptionSepArg, NULL },
1686 { "-fNoOwnBookUCI", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1687 { "-sNoOwnBookUCI", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1688 { "-firstXBook", "firstHasOwnBookUCI", XrmoptionNoArg, "False" },
1689 { "-secondXBook", "secondHasOwnBookUCI", XrmoptionNoArg, "False" },
1690 { "-polyglotDir", "polyglotDir", XrmoptionSepArg, NULL },
1691 { "-usePolyglotBook", "usePolyglotBook", XrmoptionSepArg, NULL },
1692 { "-polyglotBook", "polyglotBook", XrmoptionSepArg, NULL },
1693 { "-defaultHashSize", "defaultHashSize", XrmoptionSepArg, NULL },
1694 { "-defaultCacheSizeEGTB", "defaultCacheSizeEGTB", XrmoptionSepArg, NULL },
1695 { "-defaultPathEGTB", "defaultPathEGTB", XrmoptionSepArg, NULL },
1696 { "-defaultFrcPosition", "defaultFrcPosition", XrmoptionSepArg, NULL },
1697 { "-gameListTags", "gameListTags", XrmoptionSepArg, NULL },
1698 // [HGM] I am sure AS added many more options, but we have to fish them out, from the list in winboard.c
1700 /* [HGM,HR] User-selectable board size */
1701 { "-boardWidth", "boardWidth", XrmoptionSepArg, NULL },
1702 { "-boardHeight", "boardHeight", XrmoptionSepArg, NULL },
1703 { "-matchPause", "matchPause", XrmoptionSepArg, NULL },
1705 /* [HGM] new arguments of 4.3.xx. All except first three are back-end options, which should work immediately */
1706 { "-holdingsSize", "holdingsSize", XrmoptionSepArg, NULL }, // requires extensive front-end changes to work
1707 { "-flipBlack", "flipBlack", XrmoptionSepArg, NULL }, // requires front-end changes to work
1708 { "-allWhite", "allWhite", XrmoptionSepArg, NULL }, // requires front-end changes to work
1709 { "-pieceToCharTable", "pieceToCharTable", XrmoptionSepArg, NULL },
1710 { "-alphaRank", "alphaRank", XrmoptionSepArg, NULL },
1711 { "-testClaims", "testClaims", XrmoptionSepArg, NULL },
1712 { "-checkMates", "checkMates", XrmoptionSepArg, NULL },
1713 { "-materialDraws", "materialDraws", XrmoptionSepArg, NULL },
1714 { "-trivialDraws", "trivialDraws", XrmoptionSepArg, NULL },
1715 { "-ruleMoves", "ruleMoves", XrmoptionSepArg, NULL },
1716 { "-repeatsToDraw", "repeatsToDraw", XrmoptionSepArg, NULL },
1717 { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1718 { "-userName", "userName", XrmoptionSepArg, NULL },
1719 { "-autoKibitz", "autoKibitz", XrmoptionNoArg, "True" },
1720 { "-firstTimeOdds", "firstTimeOdds", XrmoptionSepArg, NULL },
1721 { "-secondTimeOdds", "secondTimeOdds", XrmoptionSepArg, NULL },
1722 { "-timeOddsMode", "timeOddsMode", XrmoptionSepArg, NULL },
1723 { "-firstAccumulateTC", "firstAccumulateTC", XrmoptionSepArg, NULL },
1724 { "-secondAccumulateTC", "secondAccumulateTC", XrmoptionSepArg, NULL },
1725 { "-firstNPS", "firstNPS", XrmoptionSepArg, NULL },
1726 { "-secondNPS", "secondNPS", XrmoptionSepArg, NULL },
1727 { "-serverMoves", "serverMoves", XrmoptionSepArg, NULL },
1728 { "-serverPause", "serverPause", XrmoptionSepArg, NULL },
1729 { "-suppressLoadMoves", "suppressLoadMoves", XrmoptionSepArg, NULL },
1730 { "-egtFormats", "egtFormats", XrmoptionSepArg, NULL },
1731 { "-userName", "userName", XrmoptionSepArg, NULL },
1732 { "-smpCores", "smpCores", XrmoptionSepArg, NULL },
1733 { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL },
1734 { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL },
1735 { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL },
1736 { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL },
1737 { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL },
1738 { "-nameOfDebugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1739 { "-debugFile", "nameOfDebugFile", XrmoptionSepArg, NULL },
1740 { "-engineDebugOutput", "engineDebugOutput", XrmoptionSepArg, NULL },
1741 { "-noGUI", "noGUI", XrmoptionNoArg, "True" },
1742 { "-firstOptions", "firstOptions", XrmoptionSepArg, NULL },
1743 { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
1744 { "-firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
1745 { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
1749 XtActionsRec boardActions[] = {
1750 { "DrawPosition", DrawPositionProc },
1751 { "HandleUserMove", HandleUserMove },
1752 { "AnimateUserMove", AnimateUserMove },
1753 { "FileNameAction", FileNameAction },
1754 { "AskQuestionProc", AskQuestionProc },
1755 { "AskQuestionReplyAction", AskQuestionReplyAction },
1756 { "PieceMenuPopup", PieceMenuPopup },
1757 { "WhiteClock", WhiteClock },
1758 { "BlackClock", BlackClock },
1759 { "Iconify", Iconify },
1760 { "LoadSelectedProc", LoadSelectedProc },
1761 { "LoadPositionProc", LoadPositionProc },
1762 { "LoadNextPositionProc", LoadNextPositionProc },
1763 { "LoadPrevPositionProc", LoadPrevPositionProc },
1764 { "ReloadPositionProc", ReloadPositionProc },
1765 { "CopyPositionProc", CopyPositionProc },
1766 { "PastePositionProc", PastePositionProc },
1767 { "CopyGameProc", CopyGameProc },
1768 { "PasteGameProc", PasteGameProc },
1769 { "SaveGameProc", SaveGameProc },
1770 { "SavePositionProc", SavePositionProc },
1771 { "MailMoveProc", MailMoveProc },
1772 { "ReloadCmailMsgProc", ReloadCmailMsgProc },
1773 { "MachineWhiteProc", MachineWhiteProc },
1774 { "MachineBlackProc", MachineBlackProc },
1775 { "AnalysisModeProc", AnalyzeModeProc },
1776 { "AnalyzeFileProc", AnalyzeFileProc },
1777 { "TwoMachinesProc", TwoMachinesProc },
1778 { "IcsClientProc", IcsClientProc },
1779 { "EditGameProc", EditGameProc },
1780 { "EditPositionProc", EditPositionProc },
1781 { "TrainingProc", EditPositionProc },
1782 { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
1783 { "ShowGameListProc", ShowGameListProc },
1784 { "ShowMoveListProc", HistoryShowProc},
1785 { "EditTagsProc", EditCommentProc },
1786 { "EditCommentProc", EditCommentProc },
1787 { "IcsAlarmProc", IcsAlarmProc },
1788 { "IcsInputBoxProc", IcsInputBoxProc },
1789 { "AcceptProc", AcceptProc },
1790 { "DeclineProc", DeclineProc },
1791 { "RematchProc", RematchProc },
1792 { "CallFlagProc", CallFlagProc },
1793 { "DrawProc", DrawProc },
1794 { "AdjournProc", AdjournProc },
1795 { "AbortProc", AbortProc },
1796 { "ResignProc", ResignProc },
1797 { "AdjuWhiteProc", AdjuWhiteProc },
1798 { "AdjuBlackProc", AdjuBlackProc },
1799 { "AdjuDrawProc", AdjuDrawProc },
1800 { "EnterKeyProc", EnterKeyProc },
1801 { "StopObservingProc", StopObservingProc },
1802 { "StopExaminingProc", StopExaminingProc },
1803 { "BackwardProc", BackwardProc },
1804 { "ForwardProc", ForwardProc },
1805 { "ToStartProc", ToStartProc },
1806 { "ToEndProc", ToEndProc },
1807 { "RevertProc", RevertProc },
1808 { "TruncateGameProc", TruncateGameProc },
1809 { "MoveNowProc", MoveNowProc },
1810 { "RetractMoveProc", RetractMoveProc },
1811 { "AlwaysQueenProc", AlwaysQueenProc },
1812 { "AnimateDraggingProc", AnimateDraggingProc },
1813 { "AnimateMovingProc", AnimateMovingProc },
1814 { "AutoflagProc", AutoflagProc },
1815 { "AutoflipProc", AutoflipProc },
1816 { "AutobsProc", AutobsProc },
1817 { "AutoraiseProc", AutoraiseProc },
1818 { "AutosaveProc", AutosaveProc },
1819 { "BlindfoldProc", BlindfoldProc },
1820 { "FlashMovesProc", FlashMovesProc },
1821 { "FlipViewProc", FlipViewProc },
1822 { "GetMoveListProc", GetMoveListProc },
1824 { "HighlightDraggingProc", HighlightDraggingProc },
1826 { "HighlightLastMoveProc", HighlightLastMoveProc },
1827 { "IcsAlarmProc", IcsAlarmProc },
1828 { "MoveSoundProc", MoveSoundProc },
1829 { "OldSaveStyleProc", OldSaveStyleProc },
1830 { "PeriodicUpdatesProc", PeriodicUpdatesProc },
1831 { "PonderNextMoveProc", PonderNextMoveProc },
1832 { "PopupExitMessageProc", PopupExitMessageProc },
1833 { "PopupMoveErrorsProc", PopupMoveErrorsProc },
1834 { "PremoveProc", PremoveProc },
1835 { "QuietPlayProc", QuietPlayProc },
1836 { "ShowThinkingProc", ShowThinkingProc },
1837 { "HideThinkingProc", HideThinkingProc },
1838 { "TestLegalityProc", TestLegalityProc },
1839 { "InfoProc", InfoProc },
1840 { "ManProc", ManProc },
1841 { "HintProc", HintProc },
1842 { "BookProc", BookProc },
1843 { "AboutGameProc", AboutGameProc },
1844 { "DebugProc", DebugProc },
1845 { "NothingProc", NothingProc },
1846 { "CommentPopDown", (XtActionProc) CommentPopDown },
1847 { "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
1848 { "TagsPopDown", (XtActionProc) TagsPopDown },
1849 { "ErrorPopDown", (XtActionProc) ErrorPopDown },
1850 { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown },
1851 { "AnalysisPopDown", (XtActionProc) AnalysisPopDown },
1852 { "FileNamePopDown", (XtActionProc) FileNamePopDown },
1853 { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
1854 { "GameListPopDown", (XtActionProc) GameListPopDown },
1855 { "PromotionPopDown", (XtActionProc) PromotionPopDown },
1856 { "HistoryPopDown", (XtActionProc) HistoryPopDown },
1857 { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
1858 { "ShufflePopDown", (XtActionProc) ShufflePopDown },
1859 { "EnginePopDown", (XtActionProc) EnginePopDown },
1860 { "UciPopDown", (XtActionProc) UciPopDown },
1861 { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },
1862 { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },
1863 { "SettingsPopDown", (XtActionProc) SettingsPopDown },
1866 char globalTranslations[] =
1867 ":<Key>R: ResignProc() \n \
1868 :<Key>F: ToEndProc() \n \
1869 :<Key>f: ForwardProc() \n \
1870 :<Key>B: ToStartProc() \n \
1871 :<Key>b: BackwardProc() \n \
1872 :<Key>d: DrawProc() \n \
1873 :<Key>t: CallFlagProc() \n \
1874 :<Key>i: Iconify() \n \
1875 :<Key>c: Iconify() \n \
1876 :<Key>v: FlipViewProc() \n \
1877 <KeyDown>Control_L: BackwardProc() \n \
1878 <KeyUp>Control_L: ForwardProc() \n \
1879 <KeyDown>Control_R: BackwardProc() \n \
1880 <KeyUp>Control_R: ForwardProc() \n \
1881 Shift<Key>1: AskQuestionProc(\"Direct command\",\
1882 \"Send to chess program:\",,1) \n \
1883 Shift<Key>2: AskQuestionProc(\"Direct command\",\
1884 \"Send to second chess program:\",,2) \n";
1886 char boardTranslations[] =
1887 "<Btn1Down>: HandleUserMove() \n \
1888 <Btn1Up>: HandleUserMove() \n \
1889 <Btn1Motion>: AnimateUserMove() \n \
1890 Shift<Btn2Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\
1891 PieceMenuPopup(menuB) \n \
1892 Any<Btn2Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \
1893 PieceMenuPopup(menuW) \n \
1894 Shift<Btn3Down>: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD)\
1895 PieceMenuPopup(menuW) \n \
1896 Any<Btn3Down>: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD) \
1897 PieceMenuPopup(menuB) \n";
1899 char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
1900 char blackTranslations[] = "<BtnDown>: BlackClock()\n";
1902 char ICSInputTranslations[] =
1903 "<Key>Return: EnterKeyProc() \n";
1905 String xboardResources[] = {
1906 "*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
1907 "*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
1908 "*errorpopup*translations: #override\\n <Key>Return: ErrorPopDown()",
1913 /* Max possible square size */
1914 #define MAXSQSIZE 256
1916 static int xpm_avail[MAXSQSIZE];
1918 #ifdef HAVE_DIR_STRUCT
1920 /* Extract piece size from filename */
1922 xpm_getsize(name, len, ext)
1933 if ((p=strchr(name, '.')) == NULL ||
1934 StrCaseCmp(p+1, ext) != 0)
1940 while (*p && isdigit(*p))
1947 /* Setup xpm_avail */
1949 xpm_getavail(dirname, ext)
1957 for (i=0; i<MAXSQSIZE; ++i)
1960 if (appData.debugMode)
1961 fprintf(stderr, "XPM dir:%s:ext:%s:\n", dirname, ext);
1963 dir = opendir(dirname);
1966 fprintf(stderr, _("%s: Can't access XPM directory %s\n"),
1967 programName, dirname);
1971 while ((ent=readdir(dir)) != NULL) {
1972 i = xpm_getsize(ent->d_name, NAMLEN(ent), ext);
1973 if (i > 0 && i < MAXSQSIZE)
1983 xpm_print_avail(fp, ext)
1989 fprintf(fp, _("Available `%s' sizes:\n"), ext);
1990 for (i=1; i<MAXSQSIZE; ++i) {
1996 /* Return XPM piecesize closest to size */
1998 xpm_closest_to(dirname, size, ext)
2004 int sm_diff = MAXSQSIZE;
2008 xpm_getavail(dirname, ext);
2010 if (appData.debugMode)
2011 xpm_print_avail(stderr, ext);
2013 for (i=1; i<MAXSQSIZE; ++i) {
2016 diff = (diff<0) ? -diff : diff;
2017 if (diff < sm_diff) {
2025 fprintf(stderr, _("Error: No `%s' files!\n"), ext);
2031 #else /* !HAVE_DIR_STRUCT */
2032 /* If we are on a system without a DIR struct, we can't
2033 read the directory, so we can't collect a list of
2034 filenames, etc., so we can't do any size-fitting. */
2036 xpm_closest_to(dirname, size, ext)
2041 fprintf(stderr, _("\
2042 Warning: No DIR structure found on this system --\n\
2043 Unable to autosize for XPM/XIM pieces.\n\
2044 Please report this error to frankm@hiwaay.net.\n\
2045 Include system type & operating system in message.\n"));
2048 #endif /* HAVE_DIR_STRUCT */
2050 static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
2051 "magenta", "cyan", "white" };
2055 TextColors textColors[(int)NColorClasses];
2057 /* String is: "fg, bg, attr". Which is 0, 1, 2 */
2059 parse_color(str, which)
2063 char *p, buf[100], *d;
2066 if (strlen(str) > 99) /* watch bounds on buf */
2071 for (i=0; i<which; ++i) {
2078 /* Could be looking at something like:
2080 .. in which case we want to stop on a comma also */
2081 while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
2085 return -1; /* Use default for empty field */
2088 if (which == 2 || isdigit(*p))
2091 while (*p && isalpha(*p))
2096 for (i=0; i<8; ++i) {
2097 if (!StrCaseCmp(buf, cnames[i]))
2098 return which? (i+40) : (i+30);
2100 if (!StrCaseCmp(buf, "default")) return -1;
2102 fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
2107 parse_cpair(cc, str)
2111 if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
2112 fprintf(stderr, _("%s: can't parse foreground color in `%s'\n"),
2117 /* bg and attr are optional */
2118 textColors[(int)cc].bg = parse_color(str, 1);
2119 if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
2120 textColors[(int)cc].attr = 0;
2126 /* Arrange to catch delete-window events */
2127 Atom wm_delete_window;
2129 CatchDeleteWindow(Widget w, String procname)
2132 XSetWMProtocols(xDisplay, XtWindow(w), &wm_delete_window, 1);
2133 snprintf(buf, sizeof(buf), "<Message>WM_PROTOCOLS: %s() \n", procname);
2134 XtAugmentTranslations(w, XtParseTranslationTable(buf));
2140 /* this should raise the board to the top */
2141 gtk_window_present(GTK_WINDOW(GUI_Window));
2146 // eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
2148 #define BoardSize int
2149 void InitDrawingSizes(BoardSize boardSize, int flags)
2150 { // [HGM] resize is functional now, but for board format changes only (nr of ranks, files)
2151 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2153 XtGeometryResult gres;
2156 // if(!formWidget) return;
2159 * Enable shell resizing.
2161 // shellArgs[0].value = (XtArgVal) &w;
2162 // shellArgs[1].value = (XtArgVal) &h;
2163 // XtGetValues(shellWidget, shellArgs, 2);
2165 // shellArgs[4].value = 2*w; shellArgs[2].value = 10;
2166 // shellArgs[5].value = 2*h; shellArgs[3].value = 10;
2167 // XtSetValues(shellWidget, &shellArgs[2], 4);
2169 // XtSetArg(args[0], XtNdefaultDistance, &sep);
2170 // XtGetValues(formWidget, args, 1);
2172 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2173 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2176 // XtSetArg(args[0], XtNwidth, boardWidth);
2177 // XtSetArg(args[1], XtNheight, boardHeight);
2178 // XtSetValues(boardWidget, args, 2);
2180 timerWidth = (boardWidth - sep) / 2;
2181 // XtSetArg(args[0], XtNwidth, timerWidth);
2182 // XtSetValues(whiteTimerWidget, args, 1);
2183 // XtSetValues(blackTimerWidget, args, 1);
2185 // XawFormDoLayout(formWidget, False);
2187 if (appData.titleInWindow) {
2189 // XtSetArg(args[i], XtNborderWidth, &bor); i++;
2190 // XtSetArg(args[i], XtNheight, &h); i++;
2191 // XtGetValues(titleWidget, args, i);
2193 w = boardWidth - 2*bor;
2195 // XtSetArg(args[0], XtNwidth, &w);
2196 // XtGetValues(menuBarWidget, args, 1);
2197 w = boardWidth - w - sep - 2*bor - 2; // WIDTH_FUDGE
2200 // gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2201 // if (gres != XtGeometryYes && appData.debugMode) {
2203 // _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2204 // programName, gres, w, h, wr, hr);
2207 if(!formWidget) return;
2209 // XawFormDoLayout(formWidget, True);
2212 * Inhibit shell resizing.
2214 shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
2215 shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
2216 shellArgs[4].value = shellArgs[2].value = w;
2217 shellArgs[5].value = shellArgs[3].value = h;
2218 // XtSetValues(shellWidget, &shellArgs[0], 6);
2220 // [HGM] pieces: tailor piece bitmaps to needs of specific variant
2223 for(i=0; i<4; i++) {
2225 for(p=0; p<=(int)WhiteKing; p++)
2226 xpmPieceBitmap[i][p] = xpmPieceBitmap2[i][p]; // defaults
2227 if(gameInfo.variant == VariantShogi) {
2228 xpmPieceBitmap[i][(int)WhiteCannon] = xpmPieceBitmap2[i][(int)WhiteKing+1];
2229 xpmPieceBitmap[i][(int)WhiteNightrider] = xpmPieceBitmap2[i][(int)WhiteKing+2];
2230 xpmPieceBitmap[i][(int)WhiteSilver] = xpmPieceBitmap2[i][(int)WhiteKing+3];
2231 xpmPieceBitmap[i][(int)WhiteGrasshopper] = xpmPieceBitmap2[i][(int)WhiteKing+4];
2232 xpmPieceBitmap[i][(int)WhiteQueen] = xpmPieceBitmap2[i][(int)WhiteLance];
2235 if(gameInfo.variant == VariantGothic) {
2236 xpmPieceBitmap[i][(int)WhiteMarshall] = xpmPieceBitmap2[i][(int)WhiteSilver];
2240 // [HGM] why are thee ximMasks used at all? the ximPieceBitmaps seem to be never used!
2241 for(p=0; p<=(int)WhiteKing; p++)
2242 ximMaskPm[p] = ximMaskPm2[p]; // defaults
2243 if(gameInfo.variant == VariantShogi) {
2244 ximMaskPm[(int)WhiteCannon] = ximMaskPm2[(int)WhiteKing+1];
2245 ximMaskPm[(int)WhiteNightrider] = ximMaskPm2[(int)WhiteKing+2];
2246 ximMaskPm[(int)WhiteSilver] = ximMaskPm2[(int)WhiteKing+3];
2247 ximMaskPm[(int)WhiteGrasshopper] = ximMaskPm2[(int)WhiteKing+4];
2248 ximMaskPm[(int)WhiteQueen] = ximMaskPm2[(int)WhiteLance];
2251 if(gameInfo.variant == VariantGothic) {
2252 ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[i][(int)WhiteSilver];
2258 for(i=0; i<2; i++) {
2260 for(p=0; p<=(int)WhiteKing; p++)
2261 pieceBitmap[i][p] = pieceBitmap2[i][p]; // defaults
2262 if(gameInfo.variant == VariantShogi) {
2263 pieceBitmap[i][(int)WhiteCannon] = pieceBitmap2[i][(int)WhiteKing+1];
2264 pieceBitmap[i][(int)WhiteNightrider] = pieceBitmap2[i][(int)WhiteKing+2];
2265 pieceBitmap[i][(int)WhiteSilver] = pieceBitmap2[i][(int)WhiteKing+3];
2266 pieceBitmap[i][(int)WhiteGrasshopper] = pieceBitmap2[i][(int)WhiteKing+4];
2267 pieceBitmap[i][(int)WhiteQueen] = pieceBitmap2[i][(int)WhiteLance];
2270 if(gameInfo.variant == VariantGothic) {
2271 pieceBitmap[i][(int)WhiteMarshall] = pieceBitmap2[i][(int)WhiteSilver];
2287 int i, j, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
2288 XSetWindowAttributes window_attributes;
2290 Dimension timerWidth, boardWidth, boardHeight, w, h, sep, bor, wr, hr;
2291 XrmValue vFrom, vTo;
2292 XtGeometryResult gres;
2295 int forceMono = False;
2298 // [HGM] before anything else, expand any indirection files amongst options
2299 char *argvCopy[1000]; // 1000 seems enough
2300 char newArgs[10000]; // holds actual characters
2303 srandom(time(0)); // [HGM] book: make random truly random
2306 for(i=0; i<argc; i++) {
2307 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2308 //fprintf(stderr, "arg %s\n", argv[i]);
2309 if(argv[i][0] != '@') argvCopy[j++] = argv[i]; else {
2311 FILE *f = fopen(argv[i]+1, "rb");
2312 if(f == NULL) { fprintf(stderr, _("ignore %s\n"), argv[i]); continue; } // do not expand non-existing
2313 argvCopy[j++] = newArgs + k; // get ready for first argument from file
2314 while((c = fgetc(f)) != EOF) { // each line of file inserts 1 argument in the list
2316 if(j >= 1000-2) { printf(_("too many arguments\n")); exit(-1); }
2317 newArgs[k++] = 0; // terminate current arg
2318 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2319 argvCopy[j++] = newArgs + k; // get ready for next
2321 if(k >= 10000-1) { printf(_("too long arguments\n")); exit(-1); }
2334 if(appData.debugMode,1) { // OK, appData is not initialized here yet...
2335 for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
2341 setbuf(stdout, NULL);
2342 setbuf(stderr, NULL);
2345 programName = strrchr(argv[0], '/');
2346 if (programName == NULL)
2347 programName = argv[0];
2352 XtSetLanguageProc(NULL, NULL, NULL);
2353 bindtextdomain(PACKAGE, LOCALEDIR);
2354 textdomain(PACKAGE);
2358 XtAppInitialize(&appContext, "XBoard", shellOptions,
2359 XtNumber(shellOptions),
2360 &argc, argv, xboardResources, NULL, 0);
2362 gtk_init (&argc, &argv);
2364 /* parse glade file */
2366 builder = gtk_builder_new ();
2367 gtk_builder_add_from_file (builder, "gtk-interface.xml", NULL);
2369 GUI_Window = GTK_WIDGET (gtk_builder_get_object (builder, "MainWindow"));
2370 if(!GUI_Window) printf("Error: gtk_builder didn't work!\n");
2371 GUI_Board = GTK_WIDGET (gtk_builder_get_object (builder, "Board"));
2372 if(!GUI_Board) printf("Error: gtk_builder didn't work!\n");
2373 GUI_Whiteclock = GTK_WIDGET (gtk_builder_get_object (builder, "WhiteClock"));
2374 if(!GUI_Whiteclock) printf("Error: gtk_builder didn't work!\n");
2375 GUI_Blackclock = GTK_WIDGET (gtk_builder_get_object (builder, "BlackClock"));
2376 if(!GUI_Blackclock) printf("Error: gtk_builder didn't work!\n");
2378 gtk_builder_connect_signals (builder, NULL);
2379 // don't unref the builder, since we use it to get references to widgets
2380 // g_object_unref (G_OBJECT (builder));
2382 printf("DEBUG:finished building gtk\n");
2383 /* end parse glade file */
2386 fprintf(stderr, _("%s: unrecognized argument %s\n"),
2387 programName, argv[1]);
2388 fprintf(stderr, "Recognized options:\n");
2389 for(i = 0; i < XtNumber(shellOptions); i++) {
2390 j = fprintf(stderr, " %s%s", shellOptions[i].option,
2391 (shellOptions[i].argKind == XrmoptionSepArg
2393 if (i++ < XtNumber(shellOptions)) {
2394 fprintf(stderr, "%*c%s%s\n", 40 - j, ' ',
2395 shellOptions[i].option,
2396 (shellOptions[i].argKind == XrmoptionSepArg
2399 fprintf(stderr, "\n");
2405 if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
2408 if (chdir(chessDir) != 0) {
2409 fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
2416 if (p == NULL) p = "/tmp";
2417 i = strlen(p) + strlen("/.xboardXXXXXx.pgn") + 1;
2418 gameCopyFilename = (char*) malloc(i);
2419 gamePasteFilename = (char*) malloc(i);
2420 snprintf(gameCopyFilename,i, "%s/.xboard%05uc.pgn", p, getpid());
2421 snprintf(gamePasteFilename,i, "%s/.xboard%05up.pgn", p, getpid());
2423 XtGetApplicationResources(shellWidget, (XtPointer) &appData,
2424 clientResources, XtNumber(clientResources),
2427 if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
2428 /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
2429 if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL) {
2430 printf(_("Failed to open file '%s'\n"), appData.nameOfDebugFile);
2433 setbuf(debugFP, NULL);
2436 /* [HGM,HR] make sure board size is acceptable */
2437 if(appData.NrFiles > BOARD_SIZE ||
2438 appData.NrRanks > BOARD_SIZE )
2439 DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
2442 /* This feature does not work; animation needs a rewrite */
2443 appData.highlightDragging = FALSE;
2447 xDisplay = XtDisplay(shellWidget);
2448 xScreen = DefaultScreen(xDisplay);
2449 wm_delete_window = XInternAtom(xDisplay, "WM_DELETE_WINDOW", True);
2451 gameInfo.variant = StringToVariant(appData.variant);
2452 InitPosition(FALSE);
2455 * Determine boardSize
2457 gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
2460 // [HGM] as long as we have not created the possibility to change size while running, start with requested size
2461 gameInfo.boardWidth = appData.NrFiles > 0 ? appData.NrFiles : 8;
2462 gameInfo.boardHeight = appData.NrRanks > 0 ? appData.NrRanks : 8;
2463 gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
2468 InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine
2470 if (isdigit(appData.boardSize[0])) {
2471 i = sscanf(appData.boardSize, "%d,%d,%d,%d,%d,%d,%d", &squareSize,
2472 &lineGap, &clockFontPxlSize, &coordFontPxlSize,
2473 &fontPxlSize, &smallLayout, &tinyLayout);
2475 fprintf(stderr, _("%s: bad boardSize syntax %s\n"),
2476 programName, appData.boardSize);
2480 /* Find some defaults; use the nearest known size */
2481 SizeDefaults *szd, *nearest;
2482 int distance = 99999;
2483 nearest = szd = sizeDefaults;
2484 while (szd->name != NULL) {
2485 if (abs(szd->squareSize - squareSize) < distance) {
2487 distance = abs(szd->squareSize - squareSize);
2488 if (distance == 0) break;
2492 if (i < 2) lineGap = nearest->lineGap;
2493 if (i < 3) clockFontPxlSize = nearest->clockFontPxlSize;
2494 if (i < 4) coordFontPxlSize = nearest->coordFontPxlSize;
2495 if (i < 5) fontPxlSize = nearest->fontPxlSize;
2496 if (i < 6) smallLayout = nearest->smallLayout;
2497 if (i < 7) tinyLayout = nearest->tinyLayout;
2500 SizeDefaults *szd = sizeDefaults;
2501 if (*appData.boardSize == NULLCHAR) {
2502 while (DisplayWidth(xDisplay, xScreen) < szd->minScreenSize ||
2503 DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) {
2506 if (szd->name == NULL) szd--;
2508 while (szd->name != NULL &&
2509 StrCaseCmp(szd->name, appData.boardSize) != 0) szd++;
2510 if (szd->name == NULL) {
2511 fprintf(stderr, _("%s: unrecognized boardSize name %s\n"),
2512 programName, appData.boardSize);
2516 squareSize = szd->squareSize;
2517 lineGap = szd->lineGap;
2518 clockFontPxlSize = szd->clockFontPxlSize;
2519 coordFontPxlSize = szd->coordFontPxlSize;
2520 fontPxlSize = szd->fontPxlSize;
2521 smallLayout = szd->smallLayout;
2522 tinyLayout = szd->tinyLayout;
2525 printf("DEBUG::main: squareSize %d\n",squareSize);
2527 boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
2528 boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
2529 if (appData.showJail == 1) {
2530 /* Jail on top and bottom */
2531 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2532 XtSetArg(boardArgs[2], XtNheight,
2533 boardHeight + 2*(lineGap + squareSize));
2534 } else if (appData.showJail == 2) {
2536 XtSetArg(boardArgs[1], XtNwidth,
2537 boardWidth + 2*(lineGap + squareSize));
2538 XtSetArg(boardArgs[2], XtNheight, boardHeight);
2541 XtSetArg(boardArgs[1], XtNwidth, boardWidth);
2542 XtSetArg(boardArgs[2], XtNheight, boardHeight);
2546 * Determine what fonts to use.
2548 appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
2549 clockFontID = XLoadFont(xDisplay, appData.clockFont);
2550 clockFontStruct = XQueryFont(xDisplay, clockFontID);
2551 appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
2552 coordFontID = XLoadFont(xDisplay, appData.coordFont);
2553 coordFontStruct = XQueryFont(xDisplay, coordFontID);
2554 appData.font = FindFont(appData.font, fontPxlSize);
2555 countFontID = XLoadFont(xDisplay, appData.coordFont); // [HGM] holdings
2556 countFontStruct = XQueryFont(xDisplay, countFontID);
2557 // appData.font = FindFont(appData.font, fontPxlSize);
2559 xdb = XtDatabase(xDisplay);
2560 XrmPutStringResource(&xdb, "*font", appData.font);
2563 * Detect if there are not enough colors available and adapt.
2565 if (DefaultDepth(xDisplay, xScreen) <= 2) {
2566 appData.monoMode = True;
2569 if (!appData.monoMode) {
2570 vFrom.addr = (caddr_t) appData.lightSquareColor;
2571 vFrom.size = strlen(appData.lightSquareColor);
2572 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2573 if (vTo.addr == NULL) {
2574 appData.monoMode = True;
2577 lightSquareColor = *(Pixel *) vTo.addr;
2580 if (!appData.monoMode) {
2581 vFrom.addr = (caddr_t) appData.darkSquareColor;
2582 vFrom.size = strlen(appData.darkSquareColor);
2583 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2584 if (vTo.addr == NULL) {
2585 appData.monoMode = True;
2588 darkSquareColor = *(Pixel *) vTo.addr;
2591 if (!appData.monoMode) {
2592 vFrom.addr = (caddr_t) appData.whitePieceColor;
2593 vFrom.size = strlen(appData.whitePieceColor);
2594 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2595 if (vTo.addr == NULL) {
2596 appData.monoMode = True;
2599 whitePieceColor = *(Pixel *) vTo.addr;
2602 if (!appData.monoMode) {
2603 vFrom.addr = (caddr_t) appData.blackPieceColor;
2604 vFrom.size = strlen(appData.blackPieceColor);
2605 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2606 if (vTo.addr == NULL) {
2607 appData.monoMode = True;
2610 blackPieceColor = *(Pixel *) vTo.addr;
2614 if (!appData.monoMode) {
2615 vFrom.addr = (caddr_t) appData.highlightSquareColor;
2616 vFrom.size = strlen(appData.highlightSquareColor);
2617 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2618 if (vTo.addr == NULL) {
2619 appData.monoMode = True;
2622 highlightSquareColor = *(Pixel *) vTo.addr;
2626 if (!appData.monoMode) {
2627 vFrom.addr = (caddr_t) appData.premoveHighlightColor;
2628 vFrom.size = strlen(appData.premoveHighlightColor);
2629 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2630 if (vTo.addr == NULL) {
2631 appData.monoMode = True;
2634 premoveHighlightColor = *(Pixel *) vTo.addr;
2639 fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
2642 if (appData.bitmapDirectory == NULL ||
2643 appData.bitmapDirectory[0] == NULLCHAR)
2644 appData.bitmapDirectory = DEF_BITMAP_DIR;
2647 if (appData.lowTimeWarning && !appData.monoMode) {
2648 vFrom.addr = (caddr_t) appData.lowTimeWarningColor;
2649 vFrom.size = strlen(appData.lowTimeWarningColor);
2650 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
2651 if (vTo.addr == NULL)
2652 appData.monoMode = True;
2654 lowTimeWarningColor = *(Pixel *) vTo.addr;
2657 if (appData.monoMode && appData.debugMode) {
2658 fprintf(stderr, _("white pixel = 0x%lx, black pixel = 0x%lx\n"),
2659 (unsigned long) XWhitePixel(xDisplay, xScreen),
2660 (unsigned long) XBlackPixel(xDisplay, xScreen));
2663 if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
2664 parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
2665 parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||
2666 parse_cpair(ColorChannel, appData.colorChannel) < 0 ||
2667 parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
2668 parse_cpair(ColorTell, appData.colorTell) < 0 ||
2669 parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||
2670 parse_cpair(ColorRequest, appData.colorRequest) < 0 ||
2671 parse_cpair(ColorSeek, appData.colorSeek) < 0 ||
2672 parse_cpair(ColorNormal, appData.colorNormal) < 0)
2674 if (appData.colorize) {
2676 _("%s: can't parse color names; disabling colorization\n"),
2679 appData.colorize = FALSE;
2681 textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
2682 textColors[ColorNone].attr = 0;
2684 printf("DEBUG: I'm here 0\n");
2686 // XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
2692 layoutName = "tinyLayout";
2693 } else if (smallLayout) {
2694 layoutName = "smallLayout";
2696 layoutName = "normalLayout";
2698 /* Outer layoutWidget is there only to provide a name for use in
2699 resources that depend on the layout style */
2701 XtCreateManagedWidget(layoutName, formWidgetClass, shellWidget,
2702 layoutArgs, XtNumber(layoutArgs));
2704 XtCreateManagedWidget("form", formWidgetClass, layoutWidget,
2705 formArgs, XtNumber(formArgs));
2706 XtSetArg(args[0], XtNdefaultDistance, &sep);
2707 XtGetValues(formWidget, args, 1);
2710 widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
2711 XtSetArg(args[0], XtNtop, XtChainTop);
2712 XtSetArg(args[1], XtNbottom, XtChainTop);
2713 XtSetValues(menuBarWidget, args, 2);
2715 widgetList[j++] = whiteTimerWidget =
2716 XtCreateWidget("whiteTime", labelWidgetClass,
2717 formWidget, timerArgs, XtNumber(timerArgs));
2718 XtSetArg(args[0], XtNfont, clockFontStruct);
2719 XtSetArg(args[1], XtNtop, XtChainTop);
2720 XtSetArg(args[2], XtNbottom, XtChainTop);
2721 XtSetValues(whiteTimerWidget, args, 3);
2723 widgetList[j++] = blackTimerWidget =
2724 XtCreateWidget("blackTime", labelWidgetClass,
2725 formWidget, timerArgs, XtNumber(timerArgs));
2726 XtSetArg(args[0], XtNfont, clockFontStruct);
2727 XtSetArg(args[1], XtNtop, XtChainTop);
2728 XtSetArg(args[2], XtNbottom, XtChainTop);
2729 XtSetValues(blackTimerWidget, args, 3);
2730 printf("DEBUG: I'm here 1\n");
2732 if (appData.titleInWindow) {
2733 widgetList[j++] = titleWidget =
2734 XtCreateWidget("title", labelWidgetClass, formWidget,
2735 titleArgs, XtNumber(titleArgs));
2736 XtSetArg(args[0], XtNtop, XtChainTop);
2737 XtSetArg(args[1], XtNbottom, XtChainTop);
2738 XtSetValues(titleWidget, args, 2);
2741 if (appData.showButtonBar) {
2742 widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
2743 XtSetArg(args[0], XtNleft, XtChainRight); // [HGM] glue to right window edge
2744 XtSetArg(args[1], XtNright, XtChainRight); // for good run-time sizing
2745 XtSetArg(args[2], XtNtop, XtChainTop);
2746 XtSetArg(args[3], XtNbottom, XtChainTop);
2747 XtSetValues(buttonBarWidget, args, 4);
2750 // widgetList[j++] = messageWidget =
2751 // XtCreateWidget("message", labelWidgetClass, formWidget,
2752 // messageArgs, XtNumber(messageArgs));
2753 // XtSetArg(args[0], XtNtop, XtChainTop);
2754 // XtSetArg(args[1], XtNbottom, XtChainTop);
2755 // XtSetValues(messageWidget, args, 2);
2757 // widgetList[j++] = boardWidget =
2758 // XtCreateWidget("board", widgetClass, formWidget, boardArgs,
2759 // XtNumber(boardArgs));
2761 // XtManageChildren(widgetList, j);
2763 // timerWidth = (boardWidth - sep) / 2;
2764 // XtSetArg(args[0], XtNwidth, timerWidth);
2765 // XtSetValues(whiteTimerWidget, args, 1);
2766 // XtSetValues(blackTimerWidget, args, 1);
2768 // XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
2769 // XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
2770 // XtGetValues(whiteTimerWidget, args, 2);
2772 // if (appData.showButtonBar) {
2773 // XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
2774 // XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
2775 // XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
2780 * gtk set properties of widgets
2783 /* set board size */
2784 gtk_widget_set_size_request(GTK_WIDGET(GUI_Board),
2785 boardWidth,boardHeight);
2787 /* end gtk set properties of widgets */
2789 printf("DEBUG: made it.\n");
2792 * formWidget uses these constraints but they are stored
2796 // XtSetArg(args[i], XtNfromHoriz, 0); i++;
2797 // XtSetValues(menuBarWidget, args, i);
2798 // if (appData.titleInWindow) {
2799 // if (smallLayout) {
2800 // printf("DEBUG: made it a.\n");
2802 // XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2803 // XtSetValues(whiteTimerWidget, args, i);
2805 // XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2806 // XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2807 // XtSetValues(blackTimerWidget, args, i);
2809 // XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2810 // XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
2811 // XtSetValues(titleWidget, args, i);
2813 // XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2814 // XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2815 // XtSetValues(messageWidget, args, i);
2816 // if (appData.showButtonBar) {
2818 // XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2819 // XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2820 // XtSetValues(buttonBarWidget, args, i);
2823 // printf("DEBUG: made it b.\n");
2825 // XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2826 // XtSetValues(whiteTimerWidget, args, i);
2828 // XtSetArg(args[i], XtNfromVert, titleWidget); i++;
2829 // XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2830 // XtSetValues(blackTimerWidget, args, i);
2832 // XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
2833 // XtSetValues(titleWidget, args, i);
2835 // XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2836 // XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2837 // XtSetValues(messageWidget, args, i);
2838 // if (appData.showButtonBar) {
2840 // XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2841 // XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2842 // XtSetValues(buttonBarWidget, args, i);
2845 // } else { printf("DEBUG: made it c.\n");
2848 // XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2849 // XtSetValues(whiteTimerWidget, args, i);
2851 // XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
2852 // XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
2853 // XtSetValues(blackTimerWidget, args, i);
2855 // XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2856 // XtSetArg(args[i], XtNresizable, (XtArgVal) True); i++;
2857 // XtSetValues(messageWidget, args, i);
2858 // if (appData.showButtonBar) {
2860 // XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
2861 // XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
2862 // XtSetValues(buttonBarWidget, args, i);
2865 // printf("DEBUG: made it 1.\n");
2867 // XtSetArg(args[0], XtNfromVert, messageWidget);
2868 // XtSetArg(args[1], XtNtop, XtChainTop);
2869 // XtSetArg(args[2], XtNbottom, XtChainBottom);
2870 // XtSetArg(args[3], XtNleft, XtChainLeft);
2871 // XtSetArg(args[4], XtNright, XtChainRight);
2872 // XtSetValues(boardWidget, args, 5);
2874 // XtRealizeWidget(shellWidget);
2876 printf("DEBUG: made it 2.\n");
2879 * Correct the width of the message and title widgets.
2880 * It is not known why some systems need the extra fudge term.
2881 * The value "2" is probably larger than needed.
2883 // XawFormDoLayout(formWidget, False);
2885 #define WIDTH_FUDGE 2
2887 // XtSetArg(args[i], XtNborderWidth, &bor); i++;
2888 // XtSetArg(args[i], XtNheight, &h); i++;
2889 // XtGetValues(messageWidget, args, i);
2890 if (appData.showButtonBar) {
2892 // XtSetArg(args[i], XtNwidth, &w); i++;
2893 // XtGetValues(buttonBarWidget, args, i);
2894 // w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2896 // w = boardWidth - 2*bor + 1; /*!! +1 compensates for kludge below */
2899 // gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2900 if (gres != XtGeometryYes && appData.debugMode) {
2901 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2902 programName, gres, w, h, wr, hr);
2905 /* !! Horrible hack to work around bug in XFree86 4.0.1 (X11R6.4.3) */
2906 /* The size used for the child widget in layout lags one resize behind
2907 its true size, so we resize a second time, 1 pixel smaller. Yeech! */
2909 // gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
2910 if (gres != XtGeometryYes && appData.debugMode) {
2911 fprintf(stderr, _("%s: messageWidget geometry error %d %d %d %d %d\n"),
2912 programName, gres, w, h, wr, hr);
2915 // XtSetArg(args[0], XtNleft, XtChainLeft); // [HGM] glue ends for good run-time sizing
2916 // XtSetArg(args[1], XtNright, XtChainRight);
2917 // XtSetValues(messageWidget, args, 2);
2919 if (appData.titleInWindow) {
2921 // XtSetArg(args[i], XtNborderWidth, &bor); i++;
2922 // XtSetArg(args[i], XtNheight, &h); i++;
2923 // XtGetValues(titleWidget, args, i);
2925 w = boardWidth - 2*bor;
2927 // XtSetArg(args[0], XtNwidth, &w);
2928 // XtGetValues(menuBarWidget, args, 1);
2929 // w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
2932 // gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
2933 if (gres != XtGeometryYes && appData.debugMode) {
2935 _("%s: titleWidget geometry error %d %d %d %d %d\n"),
2936 programName, gres, w, h, wr, hr);
2939 // XawFormDoLayout(formWidget, True);
2941 // xBoardWindow = XtWindow(boardWidget);
2943 // [HGM] it seems the layout code ends here, but perhaps the color stuff is size independent and would
2944 // not need to go into InitDrawingSizes().
2947 if (appData.alwaysPromoteToQueen) {
2948 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Always Queen")),TRUE);
2950 if (appData.animateDragging) {
2951 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Dragging")),TRUE);
2953 if (appData.animate) {
2954 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Moving")),TRUE);
2956 if (appData.autoComment) {
2957 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Comment")),TRUE);
2959 if (appData.autoCallFlag) {
2960 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Flag")),TRUE);
2962 if (appData.autoFlipView) {
2963 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Flip View")),TRUE);
2965 if (appData.autoObserve) {
2966 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Observe")),TRUE);
2968 if (appData.autoRaiseBoard) {
2969 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Raise Board")),TRUE);
2971 if (appData.autoSaveGames) {
2972 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Save")),TRUE);
2974 if (appData.saveGameFile[0] != NULLCHAR) {
2975 /* Can't turn this off from menu */
2976 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Auto Save")),TRUE);
2977 gtk_action_set_sensitive(GTK_ACTION (gtk_builder_get_object (builder, "menuOptions.Auto Save")),FALSE);
2979 if (appData.blindfold) {
2980 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Blindfold")),TRUE);
2982 if (appData.flashCount > 0) {
2983 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Flash Moves")),TRUE);
2985 if (appData.getMoveList) {
2986 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Get Move List")),TRUE);
2989 if (appData.highlightDragging) {
2990 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Highlight Dragging")),TRUE);
2993 if (appData.highlightLastMove) {
2994 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Highlight Last Move")),TRUE);
2996 if (appData.icsAlarm) {
2997 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.ICS Alarm")),TRUE);
2999 if (appData.ringBellAfterMoves) {
3000 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Move Sound")),TRUE);
3002 if (appData.oldSaveStyle) {
3003 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Old Save Style")),TRUE);
3005 if (appData.periodicUpdates) {
3006 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Periodic Updates")),TRUE);
3008 if (appData.ponderNextMove) {
3009 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Ponder Next Move")),TRUE);
3011 if (appData.popupExitMessage) {
3012 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Popup Exit Message")),TRUE);
3014 if (appData.popupMoveErrors) {
3015 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Popup Move Errors")),TRUE);
3017 if (appData.premove) {
3018 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Premove")),TRUE);
3020 if (appData.quietPlay) {
3021 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Quit Play")),TRUE);
3023 if (appData.showCoords) {
3024 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Show Coords")),TRUE);
3026 if (appData.showThinking) {
3027 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Show Thinking")),TRUE);
3029 if (appData.testLegality) {
3030 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Test Legality")),TRUE);
3036 // ReadBitmap(&wIconPixmap, "icon_white.bm",
3037 // icon_white_bits, icon_white_width, icon_white_height);
3038 // ReadBitmap(&bIconPixmap, "icon_black.bm",
3039 // icon_black_bits, icon_black_width, icon_black_height);
3040 // iconPixmap = wIconPixmap;
3042 // XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;
3043 // XtSetValues(shellWidget, args, i);
3046 printf("DEBUG: creating svgs.\n");
3048 /* load square colors */
3049 SVGLightSquare = load_pixbuf("svg/LightSquare.svg",squareSize);
3050 SVGDarkSquare = load_pixbuf("svg/DarkSquare.svg",squareSize);
3051 SVGNeutralSquare = load_pixbuf("svg/NeutralSquare.svg",squareSize);
3053 /* use two icons to indicate if it is white's or black's turn */
3054 WhiteIcon = load_pixbuf("svg/icon_white.svg",0);
3055 BlackIcon = load_pixbuf("svg/icon_black.svg",0);
3056 WindowIcon = WhiteIcon;
3057 gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
3059 /* do resizing to a fixed aspect ratio */
3060 GUI_SetAspectRatio(0.8);
3062 /* realize window */
3063 gtk_widget_show (GUI_Window);
3065 printf("DEBUG: before created stuff squareSize %d.\n",squareSize);
3073 if (appData.animate || appData.animateDragging)
3076 printf("DEBUG: created stuff squareSize %d.\n",squareSize);
3079 // XtAugmentTranslations(formWidget,
3080 // XtParseTranslationTable(globalTranslations));
3081 // XtAugmentTranslations(boardWidget,
3082 // XtParseTranslationTable(boardTranslations));
3083 // XtAugmentTranslations(whiteTimerWidget,
3084 // XtParseTranslationTable(whiteTranslations));
3085 // XtAugmentTranslations(blackTimerWidget,
3086 // XtParseTranslationTable(blackTranslations));
3090 printf("DEBUG: back end initiated.\n");
3092 if (errorExitStatus == -1) {
3093 if (appData.icsActive) {
3094 /* We now wait until we see "login:" from the ICS before
3095 sending the logon script (problems with timestamp otherwise) */
3096 /*ICSInitScript();*/
3097 if (appData.icsInputBox) ICSInputBoxPopUp();
3100 signal(SIGINT, IntSigHandler);
3101 signal(SIGTERM, IntSigHandler);
3102 if (*appData.cmailGameName != NULLCHAR) {
3103 signal(SIGUSR1, CmailSigHandler);
3106 gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes()
3110 * Create a cursor for the board widget.
3111 * (This needs to be called after the window has been created to have access to board-window)
3114 BoardCursor = gdk_cursor_new(GDK_HAND2);
3115 gdk_window_set_cursor(GUI_Board->window, BoardCursor);
3116 gdk_cursor_destroy(BoardCursor);
3119 printf("DEBUG: going into gtk-main.\n");
3123 if (appData.debugMode) fclose(debugFP); // [DM] debug
3130 if (appData.icsActive && oldICSInteractionTitle != NULL) {
3131 DisplayIcsInteractionTitle(oldICSInteractionTitle);
3133 unlink(gameCopyFilename);
3134 unlink(gamePasteFilename);
3145 CmailSigHandler(sig)
3151 signal(SIGUSR1, SIG_IGN); /* suspend handler */
3153 /* Activate call-back function CmailSigHandlerCallBack() */
3154 OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
3156 signal(SIGUSR1, CmailSigHandler); /* re-activate handler */
3160 CmailSigHandlerCallBack(isr, closure, message, count, error)
3168 ReloadCmailMsgEvent(TRUE); /* Reload cmail msg */
3170 /**** end signal code ****/
3180 f = fopen(appData.icsLogon, "r");
3186 strcat(buf, appData.icsLogon);
3187 f = fopen(buf, "r");
3191 ProcessICSInitScript(f);
3198 EditCommentPopDown();
3209 SetMenuEnables(enab)
3214 if (!builder) return;
3215 while (enab->name != NULL) {
3216 o = gtk_builder_get_object(builder, enab->name);
3217 if(GTK_IS_WIDGET(o))
3218 gtk_widget_set_sensitive(GTK_WIDGET (o),enab->value);
3221 if(GTK_IS_ACTION(o))
3222 gtk_action_set_sensitive(GTK_ACTION (o),enab->value);
3224 DisplayError(enab->name, 0);
3230 Enables icsEnables[] = {
3231 { "menuFile.Mail Move", False },
3232 { "menuFile.Reload CMail Message", False },
3233 { "menuMode.Machine Black", False },
3234 { "menuMode.Machine White", False },
3235 { "menuMode.Analysis Mode", False },
3236 { "menuMode.Analyze File", False },
3237 { "menuMode.Two Machines", False },
3239 { "menuHelp.Hint", False },
3240 { "menuHelp.Book", False },
3241 { "menuStep.Move Now", False },
3242 { "menuOptions.Periodic Updates", False },
3243 { "menuOptions.Hide Thinking", False },
3244 { "menuOptions.Ponder Next Move", False },
3249 Enables ncpEnables[] = {
3250 { "menuFile.Mail Move", False },
3251 { "menuFile.Reload CMail Message", False },
3252 { "menuMode.Machine White", False },
3253 { "menuMode.Machine Black", False },
3254 { "menuMode.Analysis Mode", False },
3255 { "menuMode.Analyze File", False },
3256 { "menuMode.Two Machines", False },
3257 { "menuMode.ICS Client", False },
3258 { "menuMode.ICS Input Box", False },
3259 { "Action", False },
3260 { "menuStep.Revert", False },
3261 { "menuStep.Move Now", False },
3262 { "menuStep.Retract Move", False },
3263 { "menuOptions.Auto Comment", False },
3264 { "menuOptions.Auto Flag", False },
3265 { "menuOptions.Auto Flip View", False },
3266 { "menuOptions.Auto Observe", False },
3267 { "menuOptions.Auto Raise Board", False },
3268 { "menuOptions.Get Move List", False },
3269 { "menuOptions.ICS Alarm", False },
3270 { "menuOptions.Move Sound", False },
3271 { "menuOptions.Quiet Play", False },
3272 { "menuOptions.Hide Thinking", False },
3273 { "menuOptions.Periodic Updates", False },
3274 { "menuOptions.Ponder Next Move", False },
3275 { "menuHelp.Hint", False },
3276 { "menuHelp.Book", False },
3280 Enables gnuEnables[] = {
3281 { "menuMode.ICS Client", False },
3282 { "menuMode.ICS Input Box", False },
3283 { "menuAction.Accept", False },
3284 { "menuAction.Decline", False },
3285 { "menuAction.Rematch", False },
3286 { "menuAction.Adjourn", False },
3287 { "menuAction.Stop Examining", False },
3288 { "menuAction.Stop Observing", False },
3289 { "menuStep.Revert", False },
3290 { "menuOptions.Auto Comment", False },
3291 { "menuOptions.Auto Observe", False },
3292 { "menuOptions.Auto Raise Board", False },
3293 { "menuOptions.Get Move List", False },
3294 { "menuOptions.Premove", False },
3295 { "menuOptions.Quiet Play", False },
3297 /* The next two options rely on SetCmailMode being called *after* */
3298 /* SetGNUMode so that when GNU is being used to give hints these */
3299 /* menu options are still available */
3301 { "menuFile.Mail Move", False },
3302 { "menuFile.Reload CMail Message", False },
3306 Enables cmailEnables[] = {
3308 { "menuAction.Call Flag", False },
3309 { "menuAction.Draw", True },
3310 { "menuAction.Adjourn", False },
3311 { "menuAction.Abort", False },
3312 { "menuAction.Stop Observing", False },
3313 { "menuAction.Stop Examining", False },
3314 { "menuFile.Mail Move", True },
3315 { "menuFile.Reload CMail Message", True },
3319 Enables trainingOnEnables[] = {
3320 { "menuMode.Edit Comment", False },
3321 { "menuMode.Pause", False },
3322 { "menuStep.Forward", False },
3323 { "menuStep.Backward", False },
3324 { "menuStep.Forward to End", False },
3325 { "menuStep.Back to Start", False },
3326 { "menuStep.Move Now", False },
3327 { "menuStep.Truncate Game", False },
3331 Enables trainingOffEnables[] = {
3332 { "menuMode.Edit Comment", True },
3333 { "menuMode.Pause", True },
3334 { "menuStep.Forward", True },
3335 { "menuStep.Backward", True },
3336 { "menuStep.Forward to End", True },
3337 { "menuStep.Back to Start", True },
3338 { "menuStep.Move Now", True },
3339 { "menuStep.Truncate Game", True },
3343 Enables machineThinkingEnables[] = {
3344 { "menuFile.Load Game", False },
3345 { "menuFile.Load Next Game", False },
3346 { "menuFile.Load Previous Game", False },
3347 { "menuFile.Reload Same Game", False },
3348 { "menuFile.Paste Game", False },
3349 { "menuFile.Load Position", False },
3350 { "menuFile.Load Next Position", False },
3351 { "menuFile.Load Previous Position", False },
3352 { "menuFile.Reload Same Position", False },
3353 { "menuFile.Paste Position", False },
3354 { "menuMode.Machine White", False },
3355 { "menuMode.Machine Black", False },
3356 { "menuMode.Two Machines", False },
3357 { "menuStep.Retract Move", False },
3361 Enables userThinkingEnables[] = {
3362 { "menuFile.Load Game", True },
3363 { "menuFile.Load Next Game", True },
3364 { "menuFile.Load Previous Game", True },
3365 { "menuFile.Reload Same Game", True },
3366 { "menuFile.Paste Game", True },
3367 { "menuFile.Load Position", True },
3368 { "menuFile.Load Next Position", True },
3369 { "menuFile.Load Previous Position", True },
3370 { "menuFile.Reload Same Position", True },
3371 { "menuFile.Paste Position", True },
3372 { "menuMode.Machine White", True },
3373 { "menuMode.Machine Black", True },
3374 { "menuMode.Two Machines", True },
3375 { "menuStep.Retract Move", True },
3381 SetMenuEnables(icsEnables);
3384 if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */
3385 XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
3392 SetMenuEnables(ncpEnables);
3398 SetMenuEnables(gnuEnables);
3404 SetMenuEnables(cmailEnables);
3410 SetMenuEnables(trainingOnEnables);
3411 if (appData.showButtonBar) {
3412 XtSetSensitive(buttonBarWidget, False);
3418 SetTrainingModeOff()
3420 SetMenuEnables(trainingOffEnables);
3421 if (appData.showButtonBar) {
3422 XtSetSensitive(buttonBarWidget, True);
3427 SetUserThinkingEnables()
3429 if (appData.noChessProgram) return;
3430 SetMenuEnables(userThinkingEnables);
3434 SetMachineThinkingEnables()
3436 if (appData.noChessProgram) return;
3437 SetMenuEnables(machineThinkingEnables);
3439 case MachinePlaysBlack:
3440 case MachinePlaysWhite:
3441 case TwoMachinesPlay:
3442 XtSetSensitive(XtNameToWidget(menuBarWidget,
3443 ModeToWidgetName(gameMode)), True);
3450 #define Abs(n) ((n)<0 ? -(n) : (n))
3453 * Find a font that matches "pattern" that is as close as
3454 * possible to the targetPxlSize. Prefer fonts that are k
3455 * pixels smaller to fonts that are k pixels larger. The
3456 * pattern must be in the X Consortium standard format,
3457 * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
3458 * The return value should be freed with XtFree when no
3461 char *FindFont(pattern, targetPxlSize)
3465 char **fonts, *p, *best, *scalable, *scalableTail;
3466 int i, j, nfonts, minerr, err, pxlSize;
3469 char **missing_list;
3471 char *def_string, *base_fnt_lst, strInt[3];
3473 XFontStruct **fnt_list;
3475 base_fnt_lst = calloc(1, strlen(pattern) + 3);
3476 sprintf(strInt, "%d", targetPxlSize);
3477 p = strstr(pattern, "--");
3478 strncpy(base_fnt_lst, pattern, p - pattern + 2);
3479 strcat(base_fnt_lst, strInt);
3480 strcat(base_fnt_lst, strchr(p + 2, '-'));
3482 if ((fntSet = XCreateFontSet(xDisplay,
3486 &def_string)) == NULL) {
3488 fprintf(stderr, _("Unable to create font set.\n"));
3492 nfonts = XFontsOfFontSet(fntSet, &fnt_list, &fonts);
3494 fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
3496 fprintf(stderr, _("%s: no fonts match pattern %s\n"),
3497 programName, pattern);
3505 for (i=0; i<nfonts; i++) {
3508 if (*p != '-') continue;
3510 if (*p == NULLCHAR) break;
3511 if (*p++ == '-') j++;
3513 if (j < 7) continue;
3516 scalable = fonts[i];
3519 err = pxlSize - targetPxlSize;
3520 if (Abs(err) < Abs(minerr) ||
3521 (minerr > 0 && err < 0 && -err == minerr)) {
3527 if (scalable && Abs(minerr) > appData.fontSizeTolerance) {
3528 /* If the error is too big and there is a scalable font,
3529 use the scalable font. */
3530 int headlen = scalableTail - scalable;
3531 p = (char *) XtMalloc(strlen(scalable) + 10);
3532 while (isdigit(*scalableTail)) scalableTail++;
3533 sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
3535 p = (char *) XtMalloc(strlen(best) + 1);
3538 if (appData.debugMode) {
3539 fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"),
3540 pattern, targetPxlSize, p);
3543 if (missing_count > 0)
3544 XFreeStringList(missing_list);
3545 XFreeFontSet(xDisplay, fntSet);
3547 XFreeFontNames(fonts);
3554 XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
3555 | GCBackground | GCFunction | GCPlaneMask;
3556 XGCValues gc_values;
3559 gc_values.plane_mask = AllPlanes;
3560 gc_values.line_width = lineGap;
3561 gc_values.line_style = LineSolid;
3562 gc_values.function = GXcopy;
3564 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3565 gc_values.background = XBlackPixel(xDisplay, xScreen);
3566 lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3568 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3569 gc_values.background = XWhitePixel(xDisplay, xScreen);
3570 coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
3571 XSetFont(xDisplay, coordGC, coordFontID);
3573 // [HGM] make font for holdings counts (white on black0
3574 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3575 gc_values.background = XBlackPixel(xDisplay, xScreen);
3576 countGC = XtGetGC(shellWidget, value_mask, &gc_values);
3577 XSetFont(xDisplay, countGC, countFontID);
3579 if (appData.monoMode) {
3580 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3581 gc_values.background = XWhitePixel(xDisplay, xScreen);
3582 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3584 gc_values.foreground = XWhitePixel(xDisplay, xScreen);
3585 gc_values.background = XBlackPixel(xDisplay, xScreen);
3586 lightSquareGC = wbPieceGC
3587 = XtGetGC(shellWidget, value_mask, &gc_values);
3589 gc_values.foreground = XBlackPixel(xDisplay, xScreen);
3590 gc_values.background = XWhitePixel(xDisplay, xScreen);
3591 darkSquareGC = bwPieceGC
3592 = XtGetGC(shellWidget, value_mask, &gc_values);
3594 if (DefaultDepth(xDisplay, xScreen) == 1) {
3595 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
3596 gc_values.function = GXcopyInverted;
3597 copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
3598 gc_values.function = GXcopy;
3599 if (XBlackPixel(xDisplay, xScreen) == 1) {
3600 bwPieceGC = darkSquareGC;
3601 wbPieceGC = copyInvertedGC;
3603 bwPieceGC = copyInvertedGC;
3604 wbPieceGC = lightSquareGC;
3608 gc_values.foreground = highlightSquareColor;
3609 gc_values.background = highlightSquareColor;
3610 highlineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3612 gc_values.foreground = premoveHighlightColor;
3613 gc_values.background = premoveHighlightColor;
3614 prelineGC = XtGetGC(shellWidget, value_mask, &gc_values);
3616 gc_values.foreground = lightSquareColor;
3617 gc_values.background = darkSquareColor;
3618 lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3620 gc_values.foreground = darkSquareColor;
3621 gc_values.background = lightSquareColor;
3622 darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3624 gc_values.foreground = jailSquareColor;
3625 gc_values.background = jailSquareColor;
3626 jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
3628 gc_values.foreground = whitePieceColor;
3629 gc_values.background = darkSquareColor;
3630 wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3632 gc_values.foreground = whitePieceColor;
3633 gc_values.background = lightSquareColor;
3634 wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3636 gc_values.foreground = whitePieceColor;
3637 gc_values.background = jailSquareColor;
3638 wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3640 gc_values.foreground = blackPieceColor;
3641 gc_values.background = darkSquareColor;
3642 bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3644 gc_values.foreground = blackPieceColor;
3645 gc_values.background = lightSquareColor;
3646 blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3648 gc_values.foreground = blackPieceColor;
3649 gc_values.background = jailSquareColor;
3650 bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
3657 WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen, WhiteKing,
3658 BlackPawn, BlackKnight, BlackBishop, BlackRook, BlackQueen, BlackKing,
3661 SVGpieces[WhitePawn] = load_pixbuf("svg/WhitePawn.svg",squareSize);
3662 SVGpieces[WhiteKnight] = load_pixbuf("svg/WhiteKnight.svg",squareSize);
3663 SVGpieces[WhiteBishop] = load_pixbuf("svg/WhiteBishop.svg",squareSize);
3664 SVGpieces[WhiteRook] = load_pixbuf("svg/WhiteRook.svg",squareSize);
3665 SVGpieces[WhiteQueen] = load_pixbuf("svg/WhiteQueen.svg",squareSize);
3666 SVGpieces[WhiteKing] = load_pixbuf("svg/WhiteKing.svg",squareSize);
3668 SVGpieces[BlackPawn] = load_pixbuf("svg/BlackPawn.svg",squareSize);
3669 SVGpieces[BlackKnight] = load_pixbuf("svg/BlackKnight.svg",squareSize);
3670 SVGpieces[BlackBishop] = load_pixbuf("svg/BlackBishop.svg",squareSize);
3671 SVGpieces[BlackRook] = load_pixbuf("svg/BlackRook.svg",squareSize);
3672 SVGpieces[BlackQueen] = load_pixbuf("svg/BlackQueen.svg",squareSize);
3673 SVGpieces[BlackKing] = load_pixbuf("svg/BlackKing.svg",squareSize);
3683 if (lineGap == 0) return;
3685 /* [HR] Split this into 2 loops for non-square boards. */
3687 for (i = 0; i < BOARD_HEIGHT + 1; i++) {
3688 gridSegments[i].x1 = 0;
3689 gridSegments[i].x2 =
3690 lineGap + BOARD_WIDTH * (squareSize + lineGap);
3691 gridSegments[i].y1 = gridSegments[i].y2
3692 = lineGap / 2 + (i * (squareSize + lineGap));
3695 for (j = 0; j < BOARD_WIDTH + 1; j++) {
3696 gridSegments[j + i].y1 = 0;
3697 gridSegments[j + i].y2 =
3698 lineGap + BOARD_HEIGHT * (squareSize + lineGap);
3699 gridSegments[j + i].x1 = gridSegments[j + i].x2
3700 = lineGap / 2 + (j * (squareSize + lineGap));
3704 static void MenuBarSelect(w, addr, index)
3709 XtActionProc proc = (XtActionProc) addr;
3711 (proc)(NULL, NULL, NULL, NULL);
3714 void CreateMenuBarPopup(parent, name, mb)
3724 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
3727 XtSetArg(args[j], XtNleftMargin, 20); j++;
3728 XtSetArg(args[j], XtNrightMargin, 20); j++;
3730 while (mi->string != NULL) {
3731 if (strcmp(mi->string, "----") == 0) {
3732 entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
3735 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string)));
3736 entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
3738 XtAddCallback(entry, XtNcallback,
3739 (XtCallbackProc) MenuBarSelect,
3740 (caddr_t) mi->proc);
3746 Widget CreateMenuBar(mb)
3750 Widget anchor, menuBar;
3752 char menuName[MSG_SIZ];
3755 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
3756 XtSetArg(args[j], XtNvSpace, 0); j++;
3757 XtSetArg(args[j], XtNborderWidth, 0); j++;
3758 menuBar = XtCreateWidget("menuBar", boxWidgetClass,
3759 formWidget, args, j);
3761 while (mb->name != NULL) {
3762 strcpy(menuName, "menu");
3763 strcat(menuName, mb->name);
3765 XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;
3768 shortName[0] = _(mb->name)[0];
3769 shortName[1] = NULLCHAR;
3770 XtSetArg(args[j], XtNlabel, XtNewString(shortName)); j++;
3773 XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++;
3776 XtSetArg(args[j], XtNborderWidth, 0); j++;
3777 anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
3779 CreateMenuBarPopup(menuBar, menuName, mb);
3785 Widget CreateButtonBar(mi)
3789 Widget button, buttonBar;
3793 XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++;
3795 XtSetArg(args[j], XtNhSpace, 0); j++;
3797 XtSetArg(args[j], XtNborderWidth, 0); j++;
3798 XtSetArg(args[j], XtNvSpace, 0); j++;
3799 buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
3800 formWidget, args, j);
3802 while (mi->string != NULL) {
3805 XtSetArg(args[j], XtNinternalWidth, 2); j++;
3806 XtSetArg(args[j], XtNborderWidth, 0); j++;
3808 XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); j++;
3809 button = XtCreateManagedWidget(mi->string, commandWidgetClass,
3810 buttonBar, args, j);
3811 XtAddCallback(button, XtNcallback,
3812 (XtCallbackProc) MenuBarSelect,
3813 (caddr_t) mi->proc);
3820 CreatePieceMenu(name, color)
3827 ChessSquare selection;
3829 menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
3830 boardWidget, args, 0);
3832 for (i = 0; i < PIECE_MENU_SIZE; i++) {
3833 String item = pieceMenuStrings[color][i];
3835 if (strcmp(item, "----") == 0) {
3836 entry = XtCreateManagedWidget(item, smeLineObjectClass,
3839 XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
3840 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
3842 selection = pieceMenuTranslation[color][i];
3843 XtAddCallback(entry, XtNcallback,
3844 (XtCallbackProc) PieceMenuSelect,
3845 (caddr_t) selection);
3846 if (selection == WhitePawn || selection == BlackPawn) {
3847 XtSetArg(args[0], XtNpopupOnEntry, entry);
3848 XtSetValues(menu, args, 1);
3861 ChessSquare selection;
3863 // whitePieceMenu = CreatePieceMenu("menuW", 0);
3864 // blackPieceMenu = CreatePieceMenu("menuB", 1);
3866 // XtRegisterGrabAction(PieceMenuPopup, True,
3867 // (unsigned)(ButtonPressMask|ButtonReleaseMask),
3868 // GrabModeAsync, GrabModeAsync);
3870 // XtSetArg(args[0], XtNlabel, _("Drop"));
3871 // dropMenu = XtCreatePopupShell("menuD", simpleMenuWidgetClass,
3872 // boardWidget, args, 1);
3873 // for (i = 0; i < DROP_MENU_SIZE; i++) {
3874 // String item = dropMenuStrings[i];
3876 // if (strcmp(item, "----") == 0) {
3877 // entry = XtCreateManagedWidget(item, smeLineObjectClass,
3878 // dropMenu, NULL, 0);
3880 // XtSetArg(args[0], XtNlabel, XtNewString(_(item)));
3881 // entry = XtCreateManagedWidget(item, smeBSBObjectClass,
3882 // dropMenu, args, 1);
3883 // selection = dropMenuTranslation[i];
3884 // XtAddCallback(entry, XtNcallback,
3885 // (XtCallbackProc) DropMenuSelect,
3886 // (caddr_t) selection);
3891 void SetupDropMenu()
3899 for (i=0; i<sizeof(dmEnables)/sizeof(DropMenuEnables); i++) {
3900 entry = XtNameToWidget(dropMenu, dmEnables[i].widget);
3901 p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,
3902 dmEnables[i].piece);
3903 XtSetSensitive(entry, p != NULL || !appData.testLegality
3904 /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse
3905 && !appData.icsActive));
3907 while (p && *p++ == dmEnables[i].piece) count++;
3908 snprintf(label, sizeof(label), "%s %d", dmEnables[i].widget, count);
3910 XtSetArg(args[j], XtNlabel, label); j++;
3911 XtSetValues(entry, args, j);
3915 void PieceMenuPopup(w, event, params, num_params)
3919 Cardinal *num_params;
3922 if (event->type != ButtonPress) return;
3923 if (errorUp) ErrorPopDown();
3927 whichMenu = params[0];
3929 case IcsPlayingWhite:
3930 case IcsPlayingBlack:
3932 case MachinePlaysWhite:
3933 case MachinePlaysBlack:
3934 if (appData.testLegality &&
3935 gameInfo.variant != VariantBughouse &&
3936 gameInfo.variant != VariantCrazyhouse) return;
3938 whichMenu = "menuD";
3944 if (((pmFromX = EventToSquare(event->xbutton.x, BOARD_WIDTH)) < 0) ||
3945 ((pmFromY = EventToSquare(event->xbutton.y, BOARD_HEIGHT)) < 0)) {
3946 pmFromX = pmFromY = -1;
3950 pmFromX = BOARD_WIDTH - 1 - pmFromX;
3952 pmFromY = BOARD_HEIGHT - 1 - pmFromY;
3954 XtPopupSpringLoaded(XtNameToWidget(boardWidget, whichMenu));
3957 static void PieceMenuSelect(w, piece, junk)
3962 if (pmFromX < 0 || pmFromY < 0) return;
3963 EditPositionMenuEvent(piece, pmFromX, pmFromY);
3966 static void DropMenuSelect(w, piece, junk)
3971 if (pmFromX < 0 || pmFromY < 0) return;
3972 DropMenuEvent(piece, pmFromX, pmFromY);
3975 void WhiteClock(w, event, prms, nprms)
3981 if (gameMode == EditPosition || gameMode == IcsExamining) {
3982 SetWhiteToPlayEvent();
3983 } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
3988 void BlackClock(w, event, prms, nprms)
3994 if (gameMode == EditPosition || gameMode == IcsExamining) {
3995 SetBlackToPlayEvent();
3996 } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
4003 * If the user selects on a border boundary, return -1; if off the board,
4004 * return -2. Otherwise map the event coordinate to the square.
4006 int EventToSquare(x, limit)
4014 if ((x % (squareSize + lineGap)) >= squareSize)
4016 x /= (squareSize + lineGap);
4022 static void do_flash_delay(msec)
4028 static void drawHighlight(file, rank, gc)
4034 if (lineGap == 0 || appData.blindfold) return;
4037 x = lineGap/2 + ((BOARD_WIDTH-1)-file) *
4038 (squareSize + lineGap);
4039 y = lineGap/2 + rank * (squareSize + lineGap);
4041 x = lineGap/2 + file * (squareSize + lineGap);
4042 y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) *
4043 (squareSize + lineGap);
4046 XDrawRectangle(xDisplay, xBoardWindow, gc, x, y,
4047 squareSize+lineGap, squareSize+lineGap);
4050 int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
4051 int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1;
4054 SetHighlights(fromX, fromY, toX, toY)
4055 int fromX, fromY, toX, toY;
4057 if (hi1X != fromX || hi1Y != fromY) {
4058 if (hi1X >= 0 && hi1Y >= 0) {
4059 drawHighlight(hi1X, hi1Y, lineGC);
4061 if (fromX >= 0 && fromY >= 0) {
4062 drawHighlight(fromX, fromY, highlineGC);
4065 if (hi2X != toX || hi2Y != toY) {
4066 if (hi2X >= 0 && hi2Y >= 0) {
4067 drawHighlight(hi2X, hi2Y, lineGC);
4069 if (toX >= 0 && toY >= 0) {
4070 drawHighlight(toX, toY, highlineGC);
4082 SetHighlights(-1, -1, -1, -1);
4087 SetPremoveHighlights(fromX, fromY, toX, toY)
4088 int fromX, fromY, toX, toY;
4090 if (pm1X != fromX || pm1Y != fromY) {
4091 if (pm1X >= 0 && pm1Y >= 0) {
4092 drawHighlight(pm1X, pm1Y, lineGC);
4094 if (fromX >= 0 && fromY >= 0) {
4095 drawHighlight(fromX, fromY, prelineGC);
4098 if (pm2X != toX || pm2Y != toY) {
4099 if (pm2X >= 0 && pm2Y >= 0) {
4100 drawHighlight(pm2X, pm2Y, lineGC);
4102 if (toX >= 0 && toY >= 0) {
4103 drawHighlight(toX, toY, prelineGC);
4113 ClearPremoveHighlights()
4115 SetPremoveHighlights(-1, -1, -1, -1);
4118 static void BlankSquare(x, y, color, piece, dest)
4123 if (useImages && useImageSqs) {
4127 pb = SVGLightSquare;
4132 case 2: /* neutral */
4134 pb = SVGNeutralSquare;
4137 gdk_draw_pixbuf(GDK_WINDOW(GUI_Board->window),NULL,pb,0,0,x,y,-1,-1, GDK_RGB_DITHER_NORMAL, 0, 0);
4142 gc = gdk_gc_new(GDK_WINDOW(GUI_Board->window));
4146 // gc = lightSquareGC;
4150 gdk_gc_set_rgb_fg_color(gc, &tmp);
4153 // gc = darkSquareGC;
4157 gdk_gc_set_rgb_fg_color(gc, &tmp);
4159 case 2: /* neutral */
4161 // gc = jailSquareGC;
4165 gdk_gc_set_rgb_fg_color(gc, &tmp);
4168 gdk_draw_rectangle(GDK_WINDOW(GUI_Board->window),gc,1,x,y,squareSize,squareSize);
4174 I split out the routines to draw a piece so that I could
4175 make a generic flash routine.
4177 static void monoDrawPiece_1bit(piece, square_color, x, y, dest)
4179 int square_color, x, y;
4182 /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
4183 switch (square_color) {
4185 case 2: /* neutral */
4187 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
4188 ? *pieceToOutline(piece)
4189 : *pieceToSolid(piece),
4190 dest, bwPieceGC, 0, 0,
4191 squareSize, squareSize, x, y);
4194 XCopyArea(xDisplay, (int) piece < (int) BlackPawn
4195 ? *pieceToSolid(piece)
4196 : *pieceToOutline(piece),
4197 dest, wbPieceGC, 0, 0,
4198 squareSize, squareSize, x, y);
4203 static void monoDrawPiece(piece, square_color, x, y, dest)
4205 int square_color, x, y;
4208 switch (square_color) {
4210 case 2: /* neutral */
4212 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
4213 ? *pieceToOutline(piece)
4214 : *pieceToSolid(piece),
4215 dest, bwPieceGC, 0, 0,
4216 squareSize, squareSize, x, y, 1);
4219 XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
4220 ? *pieceToSolid(piece)
4221 : *pieceToOutline(piece),
4222 dest, wbPieceGC, 0, 0,
4223 squareSize, squareSize, x, y, 1);
4228 static void colorDrawPiece(piece, square_color, x, y, dest)
4230 int square_color, x, y;
4233 printf("DEBUG::colorDrawPiece: piece %d square_color %d x %d y %d \n",piece,square_color,x,y);
4234 gdk_draw_pixbuf(GDK_WINDOW(GUI_Board->window),NULL,GDK_PIXBUF(SVGpieces[piece]),0,0,x,y,-1,-1, GDK_RGB_DITHER_NORMAL, 0, 0);
4237 // if(pieceToSolid(piece) == NULL) return; // [HGM] bitmaps: make it non-fatal if we have no bitmap;
4238 // switch (square_color) {
4239 // case 1: /* light */
4240 // XCopyPlane(xDisplay, *pieceToSolid(piece),
4241 // dest, (int) piece < (int) BlackPawn
4242 // ? wlPieceGC : blPieceGC, 0, 0,
4243 // squareSize, squareSize, x, y, 1);
4245 // case 0: /* dark */
4246 // XCopyPlane(xDisplay, *pieceToSolid(piece),
4247 // dest, (int) piece < (int) BlackPawn
4248 // ? wdPieceGC : bdPieceGC, 0, 0,
4249 // squareSize, squareSize, x, y, 1);
4251 // case 2: /* neutral */
4253 // XCopyPlane(xDisplay, *pieceToSolid(piece),
4254 // dest, (int) piece < (int) BlackPawn
4255 // ? wjPieceGC : bjPieceGC, 0, 0,
4256 // squareSize, squareSize, x, y, 1);
4261 static void colorDrawPieceImage(piece, square_color, x, y, dest)
4263 int square_color, x, y;
4268 switch (square_color) {
4270 case 2: /* neutral */
4272 if ((int)piece < (int) BlackPawn) {
4280 if ((int)piece < (int) BlackPawn) {
4288 XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
4289 dest, wlPieceGC, 0, 0,
4290 squareSize, squareSize, x, y);
4293 typedef void (*DrawFunc)();
4295 DrawFunc ChooseDrawFunc()
4297 printf("DEBUG::ChooseDrawFunc: appData.monoMode %d useImages %d\n",appData.monoMode,useImages);
4298 if (appData.monoMode) {
4299 if (DefaultDepth(xDisplay, xScreen) == 1) {
4300 return monoDrawPiece_1bit;
4302 return monoDrawPiece;
4306 return colorDrawPieceImage;
4308 return colorDrawPiece;
4312 /* [HR] determine square color depending on chess variant. */
4313 static int SquareColor(row, column)
4318 if (gameInfo.variant == VariantXiangqi) {
4319 if (column >= 3 && column <= 5 && row >= 0 && row <= 2) {
4321 } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) {
4323 } else if (row <= 4) {
4329 square_color = ((column + row) % 2) == 1;
4332 /* [hgm] holdings: next line makes all holdings squares light */
4333 if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1;
4335 return square_color;
4338 void DrawSquare(row, column, piece, do_flash)
4339 int row, column, do_flash;
4342 int square_color, x, y, direction, font_ascent, font_descent;
4345 XCharStruct overall;
4349 /* Calculate delay in milliseconds (2-delays per complete flash) */
4350 flash_delay = 500 / appData.flashRate;
4352 printf("DEBUG: linegap %d squareSize %d \n",lineGap,squareSize);
4354 /* calculate x and y coordinates from row and column */
4356 x = lineGap + ((BOARD_WIDTH-1)-column) *
4357 (squareSize + lineGap);
4358 y = lineGap + row * (squareSize + lineGap);
4360 x = lineGap + column * (squareSize + lineGap);
4361 y = lineGap + ((BOARD_HEIGHT-1)-row) *
4362 (squareSize + lineGap);
4365 square_color = SquareColor(row, column);
4367 printf("DEBUG::DrawSquare: row %d column %d piece %d do_flash %d square_color %d x %d y %d\n",row,column,piece,do_flash,square_color,x,y);
4369 if ( // [HGM] holdings: blank out area between board and holdings
4370 column == BOARD_LEFT-1 || column == BOARD_RGHT
4371 || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize)
4372 || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) {
4373 BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
4375 // [HGM] print piece counts next to holdings
4376 string[1] = NULLCHAR;
4377 if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) {
4378 string[0] = '0' + piece;
4379 XTextExtents(countFontStruct, string, 1, &direction,
4380 &font_ascent, &font_descent, &overall);
4381 if (appData.monoMode) {
4382 XDrawImageString(xDisplay, xBoardWindow, countGC,
4383 x + squareSize - overall.width - 2,
4384 y + font_ascent + 1, string, 1);
4386 XDrawString(xDisplay, xBoardWindow, countGC,
4387 x + squareSize - overall.width - 2,
4388 y + font_ascent + 1, string, 1);
4391 if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) {
4392 string[0] = '0' + piece;
4393 XTextExtents(countFontStruct, string, 1, &direction,
4394 &font_ascent, &font_descent, &overall);
4395 if (appData.monoMode) {
4396 XDrawImageString(xDisplay, xBoardWindow, countGC,
4397 x + 2, y + font_ascent + 1, string, 1);
4399 XDrawString(xDisplay, xBoardWindow, countGC,
4400 x + 2, y + font_ascent + 1, string, 1);
4404 if (piece == EmptySquare || appData.blindfold) {
4405 BlankSquare(x, y, square_color, piece, xBoardWindow);
4407 drawfunc = ChooseDrawFunc();
4408 if (do_flash && appData.flashCount > 0) {
4409 for (i=0; i<appData.flashCount; ++i) {
4411 drawfunc(piece, square_color, x, y, xBoardWindow);
4412 XSync(xDisplay, False);
4413 do_flash_delay(flash_delay);
4415 BlankSquare(x, y, square_color, piece, xBoardWindow);
4416 XSync(xDisplay, False);
4417 do_flash_delay(flash_delay);
4420 drawfunc(piece, square_color, x, y, xBoardWindow);
4424 string[1] = NULLCHAR;
4425 if (appData.showCoords && row == (flipView ? BOARD_HEIGHT-1 : 0)
4426 && column >= BOARD_LEFT && column < BOARD_RGHT) {
4427 string[0] = 'a' + column - BOARD_LEFT;
4428 XTextExtents(coordFontStruct, string, 1, &direction,
4429 &font_ascent, &font_descent, &overall);
4430 if (appData.monoMode) {
4431 XDrawImageString(xDisplay, xBoardWindow, coordGC,
4432 x + squareSize - overall.width - 2,
4433 y + squareSize - font_descent - 1, string, 1);
4435 XDrawString(xDisplay, xBoardWindow, coordGC,
4436 x + squareSize - overall.width - 2,
4437 y + squareSize - font_descent - 1, string, 1);
4440 if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) {
4441 string[0] = ONE + row;
4442 XTextExtents(coordFontStruct, string, 1, &direction,
4443 &font_ascent, &font_descent, &overall);
4444 if (appData.monoMode) {
4445 XDrawImageString(xDisplay, xBoardWindow, coordGC,
4446 x + 2, y + font_ascent + 1, string, 1);
4448 XDrawString(xDisplay, xBoardWindow, coordGC,
4449 x + 2, y + font_ascent + 1, string, 1);
4455 /* Returns 1 if there are "too many" differences between b1 and b2
4456 (i.e. more than 1 move was made) */
4457 static int too_many_diffs(b1, b2)
4463 for (i=0; i<BOARD_HEIGHT; ++i) {
4464 for (j=0; j<BOARD_WIDTH; ++j) {
4465 if (b1[i][j] != b2[i][j]) {
4466 if (++c > 4) /* Castling causes 4 diffs */
4475 /* Matrix describing castling maneuvers */
4476 /* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */
4477 static int castling_matrix[4][5] = {
4478 { 0, 0, 4, 3, 2 }, /* 0-0-0, white */
4479 { 0, 7, 4, 5, 6 }, /* 0-0, white */
4480 { 7, 0, 4, 3, 2 }, /* 0-0-0, black */
4481 { 7, 7, 4, 5, 6 } /* 0-0, black */
4484 /* Checks whether castling occurred. If it did, *rrow and *rcol
4485 are set to the destination (row,col) of the rook that moved.
4487 Returns 1 if castling occurred, 0 if not.
4489 Note: Only handles a max of 1 castling move, so be sure
4490 to call too_many_diffs() first.
4492 static int check_castle_draw(newb, oldb, rrow, rcol)
4499 /* For each type of castling... */
4500 for (i=0; i<4; ++i) {
4501 r = castling_matrix[i];
4503 /* Check the 4 squares involved in the castling move */
4505 for (j=1; j<=4; ++j) {
4506 if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) {
4513 /* All 4 changed, so it must be a castling move */
4522 static int damage[BOARD_SIZE][BOARD_SIZE];
4525 * event handler for redrawing the board
4527 void DrawPosition( repaint, board)
4528 /*Boolean*/int repaint;
4532 static int lastFlipView = 0;
4533 static int lastBoardValid = 0;
4534 static Board lastBoard;
4538 printf ("DEBUG::DrawPosition: start\n");
4541 if (board == NULL) {
4542 if (!lastBoardValid) return;
4545 if (!lastBoardValid || lastFlipView != flipView) {
4546 XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
4547 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
4552 * It would be simpler to clear the window with XClearWindow()
4553 * but this causes a very distracting flicker.
4556 printf ("DEBUG::DrawPosition: in draw position 0.1\n");
4557 printf("DEBUG::DrawPosition: squareSize %d\n",squareSize);
4560 if (!repaint && lastBoardValid && lastFlipView == flipView) {
4562 printf ("DEBUG::DrawPosition: in draw position 0.1a\n");
4563 /* If too much changes (begin observing new game, etc.), don't
4565 do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
4567 /* Special check for castling so we don't flash both the king
4568 and the rook (just flash the king). */
4570 if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
4571 /* Draw rook with NO flashing. King will be drawn flashing later */
4572 DrawSquare(rrow, rcol, board[rrow][rcol], 0);
4573 lastBoard[rrow][rcol] = board[rrow][rcol];
4577 /* First pass -- Draw (newly) empty squares and repair damage.
4578 This prevents you from having a piece show up twice while it
4579 is flashing on its new square */
4580 for (i = 0; i < BOARD_HEIGHT; i++)
4581 for (j = 0; j < BOARD_WIDTH; j++)
4582 if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
4584 DrawSquare(i, j, board[i][j], 0);
4585 damage[i][j] = False;
4588 /* Second pass -- Draw piece(s) in new position and flash them */
4589 for (i = 0; i < BOARD_HEIGHT; i++)
4590 for (j = 0; j < BOARD_WIDTH; j++)
4591 if (board[i][j] != lastBoard[i][j]) {
4592 DrawSquare(i, j, board[i][j], do_flash);
4595 printf("DEBUG::DrawPosition: in else linegap %d squareSize %d\n",lineGap,squareSize);
4598 /* todo move GC to setupgc */
4599 GdkGC *gtklineGC=NULL;
4602 gtklineGC = gdk_gc_new(GDK_WINDOW(GUI_Board->window));
4607 gdk_gc_set_rgb_fg_color(gtklineGC, &tmp);
4612 gdk_gc_set_rgb_bg_color(gtklineGC, &tmp);
4614 gdk_draw_segments(GUI_Board->window,gtklineGC,
4615 gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2 );
4619 for (i = 0; i < BOARD_HEIGHT; i++)
4620 for (j = 0; j < BOARD_WIDTH; j++) {
4621 printf("DEBUG::DrawPosition: squareSize %d\n",squareSize);
4622 DrawSquare(i, j, board[i][j], 0);
4623 damage[i][j] = False;
4627 CopyBoard(lastBoard, board);
4629 lastFlipView = flipView;
4631 /* Draw highlights */
4632 if (pm1X >= 0 && pm1Y >= 0) {
4633 drawHighlight(pm1X, pm1Y, prelineGC);
4635 if (pm2X >= 0 && pm2Y >= 0) {
4636 drawHighlight(pm2X, pm2Y, prelineGC);
4638 if (hi1X >= 0 && hi1Y >= 0) {
4639 drawHighlight(hi1X, hi1Y, highlineGC);
4641 if (hi2X >= 0 && hi2Y >= 0) {
4642 drawHighlight(hi2X, hi2Y, highlineGC);
4645 /* If piece being dragged around board, must redraw that too */
4648 // XSync(xDisplay, False);
4653 * event handler for redrawing the board
4655 void DrawPositionProc(w, event, prms, nprms)
4661 DrawPosition(True, NULL);
4666 * event handler for parsing user moves
4668 // [HGM] This routine will need quite some reworking. Although the backend still supports the old
4669 // way of doing things, by calling UserMoveEvent() to test the legality of the move and then perform
4670 // it at the end, and doing all kind of preliminary tests here (e.g. to weed out self-captures), it
4671 // should be made to use the new way, of calling UserMoveTest early to determine the legality of the
4672 // move, (which will weed out the illegal selfcaptures and moves into the holdings, and flag promotions),
4673 // and at the end FinishMove() to perform the move after optional promotion popups.
4674 // For now I patched it to allow self-capture with King, and suppress clicks between board and holdings.
4675 void HandleUserMove(w, event, prms, nprms)
4682 Boolean saveAnimate;
4683 static int second = 0;
4685 if (w != boardWidget || errorExitStatus != -1) return;
4687 if (event->type == ButtonPress) ErrorPopDown();
4690 if (event->type == ButtonPress) {
4691 XtPopdown(promotionShell);
4692 XtDestroyWidget(promotionShell);
4693 promotionUp = False;
4701 x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
4702 y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
4703 if (!flipView && y >= 0) {
4704 y = BOARD_HEIGHT - 1 - y;
4706 if (flipView && x >= 0) {
4707 x = BOARD_WIDTH - 1 - x;
4710 /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
4711 if(event->type == ButtonPress
4712 && ( x == BOARD_LEFT-1 || x == BOARD_RGHT
4713 || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize
4714 || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) )
4718 if (event->type == ButtonPress) {
4720 if (OKToStartUserMove(x, y)) {
4724 DragPieceBegin(event->xbutton.x, event->xbutton.y);
4725 if (appData.highlightDragging) {
4726 SetHighlights(x, y, -1, -1);
4734 if (event->type == ButtonPress && gameMode != EditPosition &&
4739 /* Check if clicking again on the same color piece */
4740 fromP = boards[currentMove][fromY][fromX];
4741 toP = boards[currentMove][y][x];
4742 if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.
4743 WhitePawn <= toP && toP <= WhiteKing) || // For now I made it less critical by exempting King
4744 (BlackPawn <= fromP && fromP < BlackKing && // moves, to not interfere with FRC castlings.
4745 BlackPawn <= toP && toP <= BlackKing)) {
4746 /* Clicked again on same color piece -- changed his mind */
4747 second = (x == fromX && y == fromY);
4748 if (appData.highlightDragging) {
4749 SetHighlights(x, y, -1, -1);
4753 if (OKToStartUserMove(x, y)) {
4756 DragPieceBegin(event->xbutton.x, event->xbutton.y);
4762 if (event->type == ButtonRelease && x == fromX && y == fromY) {
4763 DragPieceEnd(event->xbutton.x, event->xbutton.y);
4764 if (appData.animateDragging) {
4765 /* Undo animation damage if any */
4766 DrawPosition(FALSE, NULL);
4769 /* Second up/down in same square; just abort move */
4774 ClearPremoveHighlights();
4776 /* First upclick in same square; start click-click mode */
4777 SetHighlights(x, y, -1, -1);
4782 /* Completed move */
4785 saveAnimate = appData.animate;
4786 if (event->type == ButtonPress) {
4787 /* Finish clickclick move */
4788 if (appData.animate || appData.highlightLastMove) {
4789 SetHighlights(fromX, fromY, toX, toY);
4794 /* Finish drag move */
4795 if (appData.highlightLastMove) {
4796 SetHighlights(fromX, fromY, toX, toY);
4800 DragPieceEnd(event->xbutton.x, event->xbutton.y);
4801 /* Don't animate move and drag both */
4802 appData.animate = FALSE;
4804 if (IsPromotion(fromX, fromY, toX, toY)) {
4805 if (appData.alwaysPromoteToQueen) {
4806 UserMoveEvent(fromX, fromY, toX, toY, 'q');
4807 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
4808 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
4811 SetHighlights(fromX, fromY, toX, toY);
4815 UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
4816 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
4817 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
4820 appData.animate = saveAnimate;
4821 if (appData.animate || appData.animateDragging) {
4822 /* Undo animation damage if needed */
4823 DrawPosition(FALSE, NULL);
4827 void AnimateUserMove (Widget w, XEvent * event,
4828 String * params, Cardinal * nParams)
4830 DragPieceMove(event->xmotion.x, event->xmotion.y);
4833 Widget CommentCreate(name, text, mutable, callback, lines)
4835 int /*Boolean*/ mutable;
4836 XtCallbackProc callback;
4840 Widget shell, layout, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
4845 XtSetArg(args[j], XtNwidth, &bw_width); j++;
4846 XtGetValues(boardWidget, args, j);
4849 XtSetArg(args[j], XtNresizable, True); j++;
4852 XtCreatePopupShell(name, topLevelShellWidgetClass,
4853 shellWidget, args, j);
4856 XtCreatePopupShell(name, transientShellWidgetClass,
4857 shellWidget, args, j);
4860 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
4861 layoutArgs, XtNumber(layoutArgs));
4863 XtCreateManagedWidget("form", formWidgetClass, layout,
4864 formArgs, XtNumber(formArgs));
4868 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
4869 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
4871 XtSetArg(args[j], XtNstring, text); j++;
4872 XtSetArg(args[j], XtNtop, XtChainTop); j++;
4873 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
4874 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
4875 XtSetArg(args[j], XtNright, XtChainRight); j++;
4876 XtSetArg(args[j], XtNresizable, True); j++;
4877 XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/
4879 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
4881 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
4882 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
4884 XtSetArg(args[j], XtNautoFill, True); j++;
4885 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
4887 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
4891 XtSetArg(args[j], XtNfromVert, edit); j++;
4892 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
4893 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
4894 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
4895 XtSetArg(args[j], XtNright, XtChainLeft); j++;
4897 XtCreateManagedWidget(_("ok"), commandWidgetClass, form, args, j);
4898 XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
4901 XtSetArg(args[j], XtNfromVert, edit); j++;
4902 XtSetArg(args[j], XtNfromHoriz, b_ok); j++;
4903 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
4904 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
4905 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
4906 XtSetArg(args[j], XtNright, XtChainLeft); j++;
4908 XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j);
4909 XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
4912 XtSetArg(args[j], XtNfromVert, edit); j++;
4913 XtSetArg(args[j], XtNfromHoriz, b_cancel); j++;
4914 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
4915 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
4916 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
4917 XtSetArg(args[j], XtNright, XtChainLeft); j++;
4919 XtCreateManagedWidget(_("clear"), commandWidgetClass, form, args, j);
4920 XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
4923 XtSetArg(args[j], XtNfromVert, edit); j++;
4924 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
4925 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
4926 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
4927 XtSetArg(args[j], XtNright, XtChainLeft); j++;
4929 XtCreateManagedWidget(_("close"), commandWidgetClass, form, args, j);
4930 XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
4933 XtSetArg(args[j], XtNfromVert, edit); j++;
4934 XtSetArg(args[j], XtNfromHoriz, b_close); j++;
4935 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
4936 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
4937 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
4938 XtSetArg(args[j], XtNright, XtChainLeft); j++;
4940 XtCreateManagedWidget(_("edit"), commandWidgetClass, form, args, j);
4941 XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
4944 XtRealizeWidget(shell);
4946 if (commentX == -1) {
4949 Dimension pw_height;
4950 Dimension ew_height;
4953 XtSetArg(args[j], XtNheight, &ew_height); j++;
4954 XtGetValues(edit, args, j);
4957 XtSetArg(args[j], XtNheight, &pw_height); j++;
4958 XtGetValues(shell, args, j);
4959 commentH = pw_height + (lines - 1) * ew_height;
4960 commentW = bw_width - 16;
4962 XSync(xDisplay, False);
4964 /* This code seems to tickle an X bug if it is executed too soon
4965 after xboard starts up. The coordinates get transformed as if
4966 the main window was positioned at (0, 0).
4968 XtTranslateCoords(shellWidget,
4969 (bw_width - commentW) / 2, 0 - commentH / 2,
4970 &commentX, &commentY);
4972 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
4973 RootWindowOfScreen(XtScreen(shellWidget)),
4974 (bw_width - commentW) / 2, 0 - commentH / 2,
4979 if (commentY < 0) commentY = 0; /*avoid positioning top offscreen*/
4982 XtSetArg(args[j], XtNheight, commentH); j++;
4983 XtSetArg(args[j], XtNwidth, commentW); j++;
4984 XtSetArg(args[j], XtNx, commentX); j++;
4985 XtSetArg(args[j], XtNy, commentY); j++;
4986 XtSetValues(shell, args, j);
4987 XtSetKeyboardFocus(shell, edit);
4992 /* Used for analysis window and ICS input window */
4993 Widget MiscCreate(name, text, mutable, callback, lines)
4995 int /*Boolean*/ mutable;
4996 XtCallbackProc callback;
5000 Widget shell, layout, form, edit;
5002 Dimension bw_width, pw_height, ew_height, w, h;
5008 XtSetArg(args[j], XtNresizable, True); j++;
5011 XtCreatePopupShell(name, topLevelShellWidgetClass,
5012 shellWidget, args, j);
5015 XtCreatePopupShell(name, transientShellWidgetClass,
5016 shellWidget, args, j);
5019 XtCreateManagedWidget(layoutName, formWidgetClass, shell,
5020 layoutArgs, XtNumber(layoutArgs));
5022 XtCreateManagedWidget("form", formWidgetClass, layout,
5023 formArgs, XtNumber(formArgs));
5027 XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
5028 XtSetArg(args[j], XtNuseStringInPlace, False); j++;
5030 XtSetArg(args[j], XtNstring, text); j++;
5031 XtSetArg(args[j], XtNtop, XtChainTop); j++;
5032 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
5033 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
5034 XtSetArg(args[j], XtNright, XtChainRight); j++;
5035 XtSetArg(args[j], XtNresizable, True); j++;
5037 XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++;
5039 /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
5040 XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++;
5042 XtSetArg(args[j], XtNautoFill, True); j++;
5043 XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
5045 XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
5047 XtRealizeWidget(shell);
5050 XtSetArg(args[j], XtNwidth, &bw_width); j++;
5051 XtGetValues(boardWidget, args, j);
5054 XtSetArg(args[j], XtNheight, &ew_height); j++;
5055 XtGetValues(edit, args, j);
5058 XtSetArg(args[j], XtNheight, &pw_height); j++;
5059 XtGetValues(shell, args, j);
5060 h = pw_height + (lines - 1) * ew_height;
5063 XSync(xDisplay, False);
5065 /* This code seems to tickle an X bug if it is executed too soon
5066 after xboard starts up. The coordinates get transformed as if
5067 the main window was positioned at (0, 0).
5069 XtTranslateCoords(shellWidget, (bw_width - w) / 2, 0 - h / 2, &x, &y);
5071 XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
5072 RootWindowOfScreen(XtScreen(shellWidget)),
5073 (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk);
5077 if (y < 0) y = 0; /*avoid positioning top offscreen*/
5080 XtSetArg(args[j], XtNheight, h); j++;
5081 XtSetArg(args[j], XtNwidth, w); j++;
5082 XtSetArg(args[j], XtNx, x); j++;
5083 XtSetArg(args[j], XtNy, y); j++;
5084 XtSetValues(shell, args, j);
5090 static int savedIndex; /* gross that this is global */
5092 void EditCommentPopUp(index, title, text)
5101 if (text == NULL) text = "";
5103 if (editShell == NULL) {
5105 CommentCreate(title, text, True, EditCommentCallback, 4);
5106 XtRealizeWidget(editShell);
5107 CatchDeleteWindow(editShell, "EditCommentPopDown");
5109 edit = XtNameToWidget(editShell, "*form.text");
5111 XtSetArg(args[j], XtNstring, text); j++;
5112 XtSetValues(edit, args, j);
5114 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
5115 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
5116 XtSetValues(editShell, args, j);
5119 XtPopup(editShell, XtGrabNone);
5123 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
5124 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
5128 void EditCommentCallback(w, client_data, call_data)
5130 XtPointer client_data, call_data;
5138 XtSetArg(args[j], XtNlabel, &name); j++;
5139 XtGetValues(w, args, j);
5141 if (strcmp(name, _("ok")) == 0) {
5142 edit = XtNameToWidget(editShell, "*form.text");
5144 XtSetArg(args[j], XtNstring, &val); j++;
5145 XtGetValues(edit, args, j);
5146 ReplaceComment(savedIndex, val);
5147 EditCommentPopDown();
5148 } else if (strcmp(name, _("cancel")) == 0) {
5149 EditCommentPopDown();
5150 } else if (strcmp(name, _("clear")) == 0) {
5151 edit = XtNameToWidget(editShell, "*form.text");
5152 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
5153 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
5157 void EditCommentPopDown()
5162 if (!editUp) return;
5164 XtSetArg(args[j], XtNx, &commentX); j++;
5165 XtSetArg(args[j], XtNy, &commentY); j++;
5166 XtSetArg(args[j], XtNheight, &commentH); j++;
5167 XtSetArg(args[j], XtNwidth, &commentW); j++;
5168 XtGetValues(editShell, args, j);
5169 XtPopdown(editShell);
5172 XtSetArg(args[j], XtNleftBitmap, None); j++;
5173 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
5177 void ICSInputBoxPopUp()
5182 char *title = _("ICS Input");
5185 if (ICSInputShell == NULL) {
5186 ICSInputShell = MiscCreate(title, "", True, NULL, 1);
5187 tr = XtParseTranslationTable(ICSInputTranslations);
5188 edit = XtNameToWidget(ICSInputShell, "*form.text");
5189 XtOverrideTranslations(edit, tr);
5190 XtRealizeWidget(ICSInputShell);
5191 CatchDeleteWindow(ICSInputShell, "ICSInputBoxPopDown");
5194 edit = XtNameToWidget(ICSInputShell, "*form.text");
5196 XtSetArg(args[j], XtNstring, ""); j++;
5197 XtSetValues(edit, args, j);
5199 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
5200 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
5201 XtSetValues(ICSInputShell, args, j);
5204 XtPopup(ICSInputShell, XtGrabNone);
5205 XtSetKeyboardFocus(ICSInputShell, edit);
5207 ICSInputBoxUp = True;
5209 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
5210 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
5214 void ICSInputSendText()
5221 edit = XtNameToWidget(ICSInputShell, "*form.text");
5223 XtSetArg(args[j], XtNstring, &val); j++;
5224 XtGetValues(edit, args, j);
5225 SendMultiLineToICS(val);
5226 XtCallActionProc(edit, "select-all", NULL, NULL, 0);
5227 XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
5230 void ICSInputBoxPopDown()
5235 if (!ICSInputBoxUp) return;
5237 XtPopdown(ICSInputShell);
5238 ICSInputBoxUp = False;
5240 XtSetArg(args[j], XtNleftBitmap, None); j++;
5241 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.ICS Input Box"),
5245 void CommentPopUp(title, text)
5252 if (commentShell == NULL) {
5254 CommentCreate(title, text, False, CommentCallback, 4);
5255 XtRealizeWidget(commentShell);
5256 CatchDeleteWindow(commentShell, "CommentPopDown");
5258 edit = XtNameToWidget(commentShell, "*form.text");
5260 XtSetArg(args[j], XtNstring, text); j++;
5261 XtSetValues(edit, args, j);
5263 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
5264 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
5265 XtSetValues(commentShell, args, j);
5268 XtPopup(commentShell, XtGrabNone);
5269 XSync(xDisplay, False);
5274 void AnalysisPopUp(title, text)
5281 if (analysisShell == NULL) {
5282 analysisShell = MiscCreate(title, text, False, NULL, 4);
5283 XtRealizeWidget(analysisShell);
5284 CatchDeleteWindow(analysisShell, "AnalysisPopDown");
5287 edit = XtNameToWidget(analysisShell, "*form.text");
5289 XtSetArg(args[j], XtNstring, text); j++;
5290 XtSetValues(edit, args, j);
5292 XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++;
5293 XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++;
5294 XtSetValues(analysisShell, args, j);
5298 XtPopup(analysisShell, XtGrabNone);
5300 XSync(xDisplay, False);
5305 void CommentCallback(w, client_data, call_data)
5307 XtPointer client_data, call_data;
5314 XtSetArg(args[j], XtNlabel, &name); j++;
5315 XtGetValues(w, args, j);
5317 if (strcmp(name, _("close")) == 0) {
5319 } else if (strcmp(name, _("edit")) == 0) {
5326 void CommentPopDown()
5331 if (!commentUp) return;
5333 XtSetArg(args[j], XtNx, &commentX); j++;
5334 XtSetArg(args[j], XtNy, &commentY); j++;
5335 XtSetArg(args[j], XtNwidth, &commentW); j++;
5336 XtSetArg(args[j], XtNheight, &commentH); j++;
5337 XtGetValues(commentShell, args, j);
5338 XtPopdown(commentShell);
5339 XSync(xDisplay, False);
5343 void AnalysisPopDown()
5345 if (!analysisUp) return;
5346 XtPopdown(analysisShell);
5347 XSync(xDisplay, False);
5349 if (appData.icsEngineAnalyze) ExitAnalyzeMode(); /* [DM] icsEngineAnalyze */
5353 void FileNamePopUp(label, def, proc, openMode)
5360 Widget popup, layout, dialog, edit;
5366 fileProc = proc; /* I can't see a way not */
5367 fileOpenMode = openMode; /* to use globals here */
5370 XtSetArg(args[i], XtNresizable, True); i++;
5371 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
5372 XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++;
5373 fileNameShell = popup =
5374 XtCreatePopupShell("File name prompt", transientShellWidgetClass,
5375 shellWidget, args, i);
5378 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
5379 layoutArgs, XtNumber(layoutArgs));
5382 XtSetArg(args[i], XtNlabel, label); i++;
5383 XtSetArg(args[i], XtNvalue, def); i++;
5384 XtSetArg(args[i], XtNborderWidth, 0); i++;
5385 dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
5388 XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog);
5389 XawDialogAddButton(dialog, _("cancel"), FileNameCallback,
5390 (XtPointer) dialog);
5392 XtRealizeWidget(popup);
5393 CatchDeleteWindow(popup, "FileNamePopDown");
5395 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
5396 &x, &y, &win_x, &win_y, &mask);
5398 XtSetArg(args[0], XtNx, x - 10);
5399 XtSetArg(args[1], XtNy, y - 30);
5400 XtSetValues(popup, args, 2);
5402 XtPopup(popup, XtGrabExclusive);
5405 edit = XtNameToWidget(dialog, "*value");
5406 XtSetKeyboardFocus(popup, edit);
5409 void FileNamePopDown()
5411 if (!filenameUp) return;
5412 XtPopdown(fileNameShell);
5413 XtDestroyWidget(fileNameShell);
5418 void FileNameCallback(w, client_data, call_data)
5420 XtPointer client_data, call_data;
5425 XtSetArg(args[0], XtNlabel, &name);
5426 XtGetValues(w, args, 1);
5428 if (strcmp(name, _("cancel")) == 0) {
5433 FileNameAction(w, NULL, NULL, NULL);
5436 void FileNameAction(w, event, prms, nprms)
5448 name = XawDialogGetValueString(w = XtParent(w));
5450 if ((name != NULL) && (*name != NULLCHAR)) {
5452 XtPopdown(w = XtParent(XtParent(w)));
5456 p = strrchr(buf, ' ');
5463 fullname = ExpandPathName(buf);
5465 ErrorPopUp(_("Error"), _("Can't open file"), FALSE);
5468 f = fopen(fullname, fileOpenMode);
5470 DisplayError(_("Failed to open file"), errno);
5472 (void) (*fileProc)(f, index, buf);
5479 XtPopdown(w = XtParent(XtParent(w)));
5485 void PromotionPopUp()
5488 Widget dialog, layout;
5490 Dimension bw_width, pw_width;
5494 XtSetArg(args[j], XtNwidth, &bw_width); j++;
5495 XtGetValues(boardWidget, args, j);
5498 XtSetArg(args[j], XtNresizable, True); j++;
5499 XtSetArg(args[j], XtNtitle, XtNewString(_("Promotion"))); j++;
5501 XtCreatePopupShell("Promotion", transientShellWidgetClass,
5502 shellWidget, args, j);
5504 XtCreateManagedWidget(layoutName, formWidgetClass, promotionShell,
5505 layoutArgs, XtNumber(layoutArgs));
5508 XtSetArg(args[j], XtNlabel, _("Promote to what?")); j++;
5509 XtSetArg(args[j], XtNborderWidth, 0); j++;
5510 dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
5513 if(gameInfo.variant != VariantShogi) {
5514 XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
5515 (XtPointer) dialog);
5516 XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
5517 (XtPointer) dialog);
5518 XawDialogAddButton(dialog, _("Bishop"), PromotionCallback,
5519 (XtPointer) dialog);
5520 XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
5521 (XtPointer) dialog);
5522 if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
5523 gameInfo.variant == VariantGiveaway) {
5524 XawDialogAddButton(dialog, _("King"), PromotionCallback,
5525 (XtPointer) dialog);
5527 if(gameInfo.variant == VariantCapablanca ||
5528 gameInfo.variant == VariantGothic ||
5529 gameInfo.variant == VariantCapaRandom) {
5530 XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback,
5531 (XtPointer) dialog);
5532 XawDialogAddButton(dialog, _("Chancellor"), PromotionCallback,
5533 (XtPointer) dialog);
5535 } else // [HGM] shogi
5537 XawDialogAddButton(dialog, _("Promote"), PromotionCallback,
5538 (XtPointer) dialog);
5539 XawDialogAddButton(dialog, _("Defer"), PromotionCallback,
5540 (XtPointer) dialog);
5542 XawDialogAddButton(dialog, _("cancel"), PromotionCallback,
5543 (XtPointer) dialog);
5545 XtRealizeWidget(promotionShell);
5546 CatchDeleteWindow(promotionShell, "PromotionPopDown");
5549 XtSetArg(args[j], XtNwidth, &pw_width); j++;
5550 XtGetValues(promotionShell, args, j);
5552 XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
5553 lineGap + squareSize/3 +
5554 ((toY == BOARD_HEIGHT-1) ^ (flipView) ?
5555 0 : 6*(squareSize + lineGap)), &x, &y);
5558 XtSetArg(args[j], XtNx, x); j++;
5559 XtSetArg(args[j], XtNy, y); j++;
5560 XtSetValues(promotionShell, args, j);
5562 XtPopup(promotionShell, XtGrabNone);
5567 void PromotionPopDown()
5569 if (!promotionUp) return;
5570 XtPopdown(promotionShell);
5571 XtDestroyWidget(promotionShell);
5572 promotionUp = False;
5575 void PromotionCallback(w, client_data, call_data)
5577 XtPointer client_data, call_data;
5583 XtSetArg(args[0], XtNlabel, &name);
5584 XtGetValues(w, args, 1);
5588 if (fromX == -1) return;
5590 if (strcmp(name, _("cancel")) == 0) {
5594 } else if (strcmp(name, _("Knight")) == 0) {
5596 } else if (strcmp(name, _("Promote")) == 0) {
5598 } else if (strcmp(name, _("Defer")) == 0) {
5601 promoChar = ToLower(name[0]);
5604 UserMoveEvent(fromX, fromY, toX, toY, promoChar);
5606 if (!appData.highlightLastMove || gotPremove) ClearHighlights();
5607 if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
5612 void ErrorCallback(w, client_data, call_data)
5614 XtPointer client_data, call_data;
5617 XtPopdown(w = XtParent(XtParent(XtParent(w))));
5619 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
5625 if (!errorUp) return;
5627 XtPopdown(errorShell);
5628 XtDestroyWidget(errorShell);
5629 if (errorExitStatus != -1) ExitEvent(errorExitStatus);
5632 void ErrorPopUp(title, label, modal)
5633 char *title, *label;
5638 printf ("DEBUG: error %s %s\n\n",title,label);
5640 dialog = gtk_message_dialog_new(GTK_WINDOW(GUI_Window),
5641 GTK_DIALOG_DESTROY_WITH_PARENT,
5646 gtk_window_set_title(GTK_WINDOW(dialog),(gchar *) title);
5649 gtk_dialog_run(GTK_DIALOG(dialog));
5650 gtk_widget_destroy(GTK_WIDGET(dialog));
5654 g_signal_connect_swapped (dialog, "response",
5655 G_CALLBACK (ErrorPopDownProc),
5658 gtk_widget_show(GTK_WIDGET(dialog));
5662 /* Disable all user input other than deleting the window */
5663 static int frozen = 0;
5667 /* Grab by a widget that doesn't accept input */
5668 // XtAddGrab(messageWidget, TRUE, FALSE);
5672 /* Undo a FreezeUI */
5675 if (!frozen) return;
5676 XtRemoveGrab(messageWidget);
5680 char *ModeToWidgetName(mode)
5684 case BeginningOfGame:
5685 if (appData.icsActive)
5686 return "menuMode.ICS Client";
5687 else if (appData.noChessProgram ||
5688 *appData.cmailGameName != NULLCHAR)
5689 return "menuMode.Edit Game";
5691 return "menuMode.Machine Black";
5692 case MachinePlaysBlack:
5693 return "menuMode.Machine Black";
5694 case MachinePlaysWhite:
5695 return "menuMode.Machine White";
5697 return "menuMode.Analysis Mode";
5699 return "menuMode.Analyze File";
5700 case TwoMachinesPlay:
5701 return "menuMode.Two Machines";
5703 return "menuMode.Edit Game";
5704 case PlayFromGameFile:
5705 return "menuFile.Load Game";
5707 return "menuMode.Edit Position";
5709 return "menuMode.Training";
5710 case IcsPlayingWhite:
5711 case IcsPlayingBlack:
5715 return "menuMode.ICS Client";
5722 void ModeHighlight()
5724 static int oldPausing = FALSE;
5725 static GameMode oldmode = (GameMode) -1;
5728 // todo this toggling of the pause button doesn't seem to work?
5729 // e.g. select pause from buttonbar doesn't activate menumode.pause
5731 // fprintf(stderr,"DEBUG: oldmode %d newmode %d oldpause %d newpause %d\n",oldmode,gameMode,oldPausing,pausing);
5734 // if (!boardWidget || !XtIsRealized(boardWidget)) return;
5736 if (pausing != oldPausing) {
5737 oldPausing = pausing;
5738 gtk_button_set_relief(GTK_BUTTON (gtk_builder_get_object (builder, "menuMode.Pause")),pausing?GTK_RELIEF_NORMAL:GTK_RELIEF_NONE);
5739 /* toggle background color in showbuttonbar */
5740 if (appData.showButtonBar) {
5742 gtk_button_pressed(GTK_BUTTON (gtk_builder_get_object (builder, "buttonbar.Pause")));
5744 gtk_button_released(GTK_BUTTON (gtk_builder_get_object (builder, "buttonbar.Pause")));
5749 wname = ModeToWidgetName(oldmode);
5751 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, wname)),True);
5755 /* Maybe all the enables should be handled here, not just this one */
5756 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuMode.Training")),
5757 gameMode == Training || gameMode == PlayFromGameFile);
5762 * Button/menu procedures
5765 int LoadGamePopUp(f, gameNumber, title)
5770 cmailMsgLoaded = FALSE;
5771 if (gameNumber == 0) {
5772 int error = GameListBuild(f);
5774 DisplayError(_("Cannot build game list"), error);
5775 } else if (!ListEmpty(&gameList) &&
5776 ((ListGame *) gameList.tailPred)->number > 1) {
5777 GameListPopUp(f, title);
5783 return LoadGame(f, gameNumber, title, FALSE);
5787 void LoadNextPositionProc(w, event, prms, nprms)
5796 void LoadPrevPositionProc(w, event, prms, nprms)
5805 void ReloadPositionProc(w, event, prms, nprms)
5814 void LoadPositionProc(w, event, prms, nprms)
5820 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
5823 FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
5826 void SaveGameProc(w, event, prms, nprms)
5832 FileNamePopUp(_("Save game file name?"),
5833 DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
5837 void SavePositionProc(w, event, prms, nprms)
5843 FileNamePopUp(_("Save position file name?"),
5844 DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
5848 void ReloadCmailMsgProc(w, event, prms, nprms)
5854 ReloadCmailMsgEvent(FALSE);
5857 void MailMoveProc(w, event, prms, nprms)
5866 /* this variable is shared between CopyPositionProc and SendPositionSelection */
5867 static char *selected_fen_position=NULL;
5870 SendPositionSelection(Widget w, Atom *selection, Atom *target,
5871 Atom *type_return, XtPointer *value_return,
5872 unsigned long *length_return, int *format_return)
5874 char *selection_tmp;
5876 if (!selected_fen_position) return False; /* should never happen */
5877 if (*target == XA_STRING){
5878 /* note: since no XtSelectionDoneProc was registered, Xt will
5879 * automatically call XtFree on the value returned. So have to
5880 * make a copy of it allocated with XtMalloc */
5881 selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
5882 strcpy(selection_tmp, selected_fen_position);
5884 *value_return=selection_tmp;
5885 *length_return=strlen(selection_tmp);
5886 *type_return=XA_STRING;
5887 *format_return = 8; /* bits per byte */
5894 /* note: when called from menu all parameters are NULL, so no clue what the
5895 * Widget which was clicked on was, or what the click event was
5897 void CopyPositionProc(w, event, prms, nprms)
5905 if (selected_fen_position) free(selected_fen_position);
5906 selected_fen_position = (char *)PositionToFEN(currentMove, NULL);
5907 if (!selected_fen_position) return;
5908 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
5910 SendPositionSelection,
5911 NULL/* lose_ownership_proc */ ,
5912 NULL/* transfer_done_proc */);
5914 free(selected_fen_position);
5915 selected_fen_position=NULL;
5919 /* function called when the data to Paste is ready */
5921 PastePositionCB(Widget w, XtPointer client_data, Atom *selection,
5922 Atom *type, XtPointer value, unsigned long *len, int *format)
5925 if (value==NULL || *len==0) return; /* nothing had been selected to copy */
5926 fenstr[*len]='\0'; /* normally this string is terminated, but be safe */
5927 EditPositionPasteFEN(fenstr);
5931 /* called when Paste Position button is pressed,
5932 * all parameters will be NULL */
5933 void PastePositionProc(w, event, prms, nprms)
5939 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
5940 /* (XtSelectionCallbackProc) */ PastePositionCB,
5941 NULL, /* client_data passed to PastePositionCB */
5943 /* better to use the time field from the event that triggered the
5944 * call to this function, but that isn't trivial to get
5952 SendGameSelection(Widget w, Atom *selection, Atom *target,
5953 Atom *type_return, XtPointer *value_return,
5954 unsigned long *length_return, int *format_return)
5956 char *selection_tmp;
5958 if (*target == XA_STRING){
5959 FILE* f = fopen(gameCopyFilename, "r");
5962 if (f == NULL) return False;
5966 selection_tmp = XtMalloc(len + 1);
5967 count = fread(selection_tmp, 1, len, f);
5969 XtFree(selection_tmp);
5972 selection_tmp[len] = NULLCHAR;
5973 *value_return = selection_tmp;
5974 *length_return = len;
5975 *type_return = XA_STRING;
5976 *format_return = 8; /* bits per byte */
5983 /* note: when called from menu all parameters are NULL, so no clue what the
5984 * Widget which was clicked on was, or what the click event was
5986 void CopyGameProc(w, event, prms, nprms)
5994 ret = SaveGameToFile(gameCopyFilename, FALSE);
5997 ret = XtOwnSelection(menuBarWidget, XA_PRIMARY,
6000 NULL/* lose_ownership_proc */ ,
6001 NULL/* transfer_done_proc */);
6004 /* function called when the data to Paste is ready */
6006 PasteGameCB(Widget w, XtPointer client_data, Atom *selection,
6007 Atom *type, XtPointer value, unsigned long *len, int *format)
6010 if (value == NULL || *len == 0) {
6011 return; /* nothing had been selected to copy */
6013 f = fopen(gamePasteFilename, "w");
6015 DisplayError(_("Can't open temp file"), errno);
6018 fwrite(value, 1, *len, f);
6021 LoadGameFromFile(gamePasteFilename, 0, gamePasteFilename, TRUE);
6024 /* called when Paste Game button is pressed,
6025 * all parameters will be NULL */
6026 void PasteGameProc(w, event, prms, nprms)
6032 XtGetSelectionValue(menuBarWidget, XA_PRIMARY, XA_STRING,
6033 /* (XtSelectionCallbackProc) */ PasteGameCB,
6034 NULL, /* client_data passed to PasteGameCB */
6036 /* better to use the time field from the event that triggered the
6037 * call to this function, but that isn't trivial to get
6047 SaveGameProc(NULL, NULL, NULL, NULL);
6050 void MachineBlackProc(w, event, prms, nprms)
6056 MachineBlackEvent();
6059 void MachineWhiteProc(w, event, prms, nprms)
6065 MachineWhiteEvent();
6068 void AnalyzeModeProc(w, event, prms, nprms)
6076 if (!first.analysisSupport) {
6077 snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy);
6078 DisplayError(buf, 0);
6081 /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */
6082 if (appData.icsActive) {
6083 if (gameMode != IcsObserving) {
6084 sprintf(buf,_("You are not observing a game"));
6085 DisplayError(buf, 0);
6087 if (appData.icsEngineAnalyze) {
6088 if (appData.debugMode)
6089 fprintf(debugFP, _("Found unexpected active ICS engine analyze \n"));
6095 /* if enable, use want disable icsEngineAnalyze */
6096 if (appData.icsEngineAnalyze) {
6101 appData.icsEngineAnalyze = TRUE;
6102 if (appData.debugMode)
6103 fprintf(debugFP, _("ICS engine analyze starting... \n"));
6105 if (!appData.showThinking)
6106 ShowThinkingProc(w,event,prms,nprms);
6111 void AnalyzeFileProc(w, event, prms, nprms)
6117 if (!first.analysisSupport) {
6119 snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy);
6120 DisplayError(buf, 0);
6125 if (!appData.showThinking)
6126 ShowThinkingProc(w,event,prms,nprms);
6129 FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
6130 AnalysisPeriodicEvent(1);
6133 void TwoMachinesProc(w, event, prms, nprms)
6142 void IcsClientProc(w, event, prms, nprms)
6151 void EditGameProc(w, event, prms, nprms)
6160 void EditPositionProc(w, event, prms, nprms)
6166 EditPositionEvent();
6169 void TrainingProc(w, event, prms, nprms)
6178 void EditCommentProc(w, event, prms, nprms)
6185 EditCommentPopDown();
6191 void IcsInputBoxProc(w, event, prms, nprms)
6197 if (ICSInputBoxUp) {
6198 ICSInputBoxPopDown();
6204 void AcceptProc(w, event, prms, nprms)
6213 void DeclineProc(w, event, prms, nprms)
6222 void RematchProc(w, event, prms, nprms)
6231 void CallFlagProc(w, event, prms, nprms)
6240 void DrawProc(w, event, prms, nprms)
6249 void AbortProc(w, event, prms, nprms)
6258 void AdjournProc(w, event, prms, nprms)
6267 void ResignProc(w, event, prms, nprms)
6276 void AdjuWhiteProc(w, event, prms, nprms)
6282 UserAdjudicationEvent(+1);
6285 void AdjuBlackProc(w, event, prms, nprms)
6291 UserAdjudicationEvent(-1);
6294 void AdjuDrawProc(w, event, prms, nprms)
6300 UserAdjudicationEvent(0);
6303 void EnterKeyProc(w, event, prms, nprms)
6309 if (ICSInputBoxUp == True)
6313 void StopObservingProc(w, event, prms, nprms)
6319 StopObservingEvent();
6322 void StopExaminingProc(w, event, prms, nprms)
6328 StopExaminingEvent();
6332 void ForwardProc(w, event, prms, nprms)
6342 void BackwardProc(w, event, prms, nprms)
6351 void ToStartProc(w, event, prms, nprms)
6360 void ToEndProc(w, event, prms, nprms)
6369 void RevertProc(w, event, prms, nprms)
6378 void TruncateGameProc(w, event, prms, nprms)
6384 TruncateGameEvent();
6386 void RetractMoveProc(w, event, prms, nprms)
6395 void MoveNowProc(w, event, prms, nprms)
6405 void AlwaysQueenProc(w, event, prms, nprms)
6413 appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
6415 if (appData.alwaysPromoteToQueen) {
6416 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6418 XtSetArg(args[0], XtNleftBitmap, None);
6420 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
6424 void AnimateDraggingProc(w, event, prms, nprms)
6432 appData.animateDragging = !appData.animateDragging;
6434 if (appData.animateDragging) {
6435 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6438 XtSetArg(args[0], XtNleftBitmap, None);
6440 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"),
6444 void AnimateMovingProc(w, event, prms, nprms)
6452 appData.animate = !appData.animate;
6454 if (appData.animate) {
6455 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6458 XtSetArg(args[0], XtNleftBitmap, None);
6460 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"),
6464 void AutocommProc(w, event, prms, nprms)
6472 appData.autoComment = !appData.autoComment;
6474 if (appData.autoComment) {
6475 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6477 XtSetArg(args[0], XtNleftBitmap, None);
6479 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
6484 void AutoflagProc(w, event, prms, nprms)
6492 appData.autoCallFlag = !appData.autoCallFlag;
6494 if (appData.autoCallFlag) {
6495 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6497 XtSetArg(args[0], XtNleftBitmap, None);
6499 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
6503 void AutoflipProc(w, event, prms, nprms)
6511 appData.autoFlipView = !appData.autoFlipView;
6513 if (appData.autoFlipView) {
6514 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6516 XtSetArg(args[0], XtNleftBitmap, None);
6518 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"),
6522 void AutobsProc(w, event, prms, nprms)
6530 appData.autoObserve = !appData.autoObserve;
6532 if (appData.autoObserve) {
6533 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6535 XtSetArg(args[0], XtNleftBitmap, None);
6537 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
6541 void AutoraiseProc(w, event, prms, nprms)
6549 appData.autoRaiseBoard = !appData.autoRaiseBoard;
6551 if (appData.autoRaiseBoard) {
6552 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6554 XtSetArg(args[0], XtNleftBitmap, None);
6556 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"),
6560 void AutosaveProc(w, event, prms, nprms)
6568 appData.autoSaveGames = !appData.autoSaveGames;
6570 if (appData.autoSaveGames) {
6571 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6573 XtSetArg(args[0], XtNleftBitmap, None);
6575 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
6579 void BlindfoldProc(w, event, prms, nprms)
6587 appData.blindfold = !appData.blindfold;
6589 if (appData.blindfold) {
6590 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6592 XtSetArg(args[0], XtNleftBitmap, None);
6594 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"),
6597 DrawPosition(True, NULL);
6600 void TestLegalityProc(w, event, prms, nprms)
6608 appData.testLegality = !appData.testLegality;
6610 if (appData.testLegality) {
6611 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6613 XtSetArg(args[0], XtNleftBitmap, None);
6615 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"),
6620 void FlashMovesProc(w, event, prms, nprms)
6628 if (appData.flashCount == 0) {
6629 appData.flashCount = 3;
6631 appData.flashCount = -appData.flashCount;
6634 if (appData.flashCount > 0) {
6635 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6637 XtSetArg(args[0], XtNleftBitmap, None);
6639 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"),
6643 void FlipViewProc(w, event, prms, nprms)
6649 flipView = !flipView;
6650 DrawPosition(True, NULL);
6653 void GetMoveListProc(w, event, prms, nprms)
6661 appData.getMoveList = !appData.getMoveList;
6663 if (appData.getMoveList) {
6664 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6667 XtSetArg(args[0], XtNleftBitmap, None);
6669 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
6674 void HighlightDraggingProc(w, event, prms, nprms)
6682 appData.highlightDragging = !appData.highlightDragging;
6684 if (appData.highlightDragging) {
6685 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6687 XtSetArg(args[0], XtNleftBitmap, None);
6689 XtSetValues(XtNameToWidget(menuBarWidget,
6690 "menuOptions.Highlight Dragging"), args, 1);
6694 void HighlightLastMoveProc(w, event, prms, nprms)
6702 appData.highlightLastMove = !appData.highlightLastMove;
6704 if (appData.highlightLastMove) {
6705 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6707 XtSetArg(args[0], XtNleftBitmap, None);
6709 XtSetValues(XtNameToWidget(menuBarWidget,
6710 "menuOptions.Highlight Last Move"), args, 1);
6713 void IcsAlarmProc(w, event, prms, nprms)
6721 appData.icsAlarm = !appData.icsAlarm;
6723 if (appData.icsAlarm) {
6724 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6726 XtSetArg(args[0], XtNleftBitmap, None);
6728 XtSetValues(XtNameToWidget(menuBarWidget,
6729 "menuOptions.ICS Alarm"), args, 1);
6732 void MoveSoundProc(w, event, prms, nprms)
6740 appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
6742 if (appData.ringBellAfterMoves) {
6743 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6745 XtSetArg(args[0], XtNleftBitmap, None);
6747 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
6752 void OldSaveStyleProc(w, event, prms, nprms)
6760 appData.oldSaveStyle = !appData.oldSaveStyle;
6762 if (appData.oldSaveStyle) {
6763 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6765 XtSetArg(args[0], XtNleftBitmap, None);
6767 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
6771 void PeriodicUpdatesProc(w, event, prms, nprms)
6779 PeriodicUpdatesEvent(!appData.periodicUpdates);
6781 if (appData.periodicUpdates) {
6782 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6784 XtSetArg(args[0], XtNleftBitmap, None);
6786 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"),
6790 void PonderNextMoveProc(w, event, prms, nprms)
6798 PonderNextMoveEvent(!appData.ponderNextMove);
6800 if (appData.ponderNextMove) {
6801 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6803 XtSetArg(args[0], XtNleftBitmap, None);
6805 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"),
6809 void PopupExitMessageProc(w, event, prms, nprms)
6817 appData.popupExitMessage = !appData.popupExitMessage;
6819 if (appData.popupExitMessage) {
6820 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6822 XtSetArg(args[0], XtNleftBitmap, None);
6824 XtSetValues(XtNameToWidget(menuBarWidget,
6825 "menuOptions.Popup Exit Message"), args, 1);
6828 void PopupMoveErrorsProc(w, event, prms, nprms)
6836 appData.popupMoveErrors = !appData.popupMoveErrors;
6838 if (appData.popupMoveErrors) {
6839 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6841 XtSetArg(args[0], XtNleftBitmap, None);
6843 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"),
6847 void PremoveProc(w, event, prms, nprms)
6855 appData.premove = !appData.premove;
6857 if (appData.premove) {
6858 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6860 XtSetArg(args[0], XtNleftBitmap, None);
6862 XtSetValues(XtNameToWidget(menuBarWidget,
6863 "menuOptions.Premove"), args, 1);
6866 void QuietPlayProc(w, event, prms, nprms)
6874 appData.quietPlay = !appData.quietPlay;
6876 if (appData.quietPlay) {
6877 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6879 XtSetArg(args[0], XtNleftBitmap, None);
6881 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
6885 void ShowThinkingProc(w, event, prms, nprms)
6893 appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
6894 ShowThinkingEvent();
6896 // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)
6897 if (appData.showThinking) {
6898 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6900 XtSetArg(args[0], XtNleftBitmap, None);
6902 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
6907 void HideThinkingProc(w, event, prms, nprms)
6915 appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent
6916 ShowThinkingEvent();
6918 if (appData.hideThinkingFromHuman) {
6919 XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
6921 XtSetArg(args[0], XtNleftBitmap, None);
6923 XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"),
6927 void InfoProc(w, event, prms, nprms)
6934 snprintf(buf, sizeof(buf), "xterm -e info --directory %s --directory . -f %s &",
6939 void ManProc(w, event, prms, nprms)
6947 if (nprms && *nprms > 0)
6951 snprintf(buf, sizeof(buf), "xterm -e man %s &", name);
6955 void HintProc(w, event, prms, nprms)
6964 void BookProc(w, event, prms, nprms)
6973 void DebugProc(w, event, prms, nprms)
6979 appData.debugMode = !appData.debugMode;
6982 void AboutGameProc(w, event, prms, nprms)
6991 void NothingProc(w, event, prms, nprms)
7000 void Iconify(w, event, prms, nprms)
7009 XtSetArg(args[0], XtNiconic, True);
7010 XtSetValues(shellWidget, args, 1);
7013 void DisplayMessage(message, extMessage)
7014 gchar *message, *extMessage;
7021 snprintf(buf, sizeof(buf), "%s %s", message, extMessage);
7024 message = extMessage;
7028 printf("TODO: message %s\n",message);
7029 gtk_label_set_text( GTK_LABEL(gtk_builder_get_object (builder, "Messages")),message);
7032 void DisplayTitle(text)
7037 char title[MSG_SIZ];
7040 if (text == NULL) text = "";
7042 if (appData.titleInWindow) {
7044 XtSetArg(args[i], XtNlabel, text); i++;
7045 XtSetValues(titleWidget, args, i);
7048 if (*text != NULLCHAR) {
7050 strcpy(title, text);
7051 } else if (appData.icsActive) {
7052 snprintf(icon, sizeof(icon), "%s", appData.icsHost);
7053 snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost);
7054 } else if (appData.cmailGameName[0] != NULLCHAR) {
7055 snprintf(icon, sizeof(icon), "%s", "CMail");
7056 snprintf(title,sizeof(title), "%s: %s", programName, "CMail");
7058 // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
7059 } else if (gameInfo.variant == VariantGothic) {
7060 strcpy(icon, programName);
7061 strcpy(title, GOTHIC);
7064 } else if (gameInfo.variant == VariantFalcon) {
7065 strcpy(icon, programName);
7066 strcpy(title, FALCON);
7068 } else if (appData.noChessProgram) {
7069 strcpy(icon, programName);
7070 strcpy(title, programName);
7072 strcpy(icon, first.tidy);
7073 snprintf(title,sizeof(title), "%s: %s", programName, first.tidy);
7076 XtSetArg(args[i], XtNiconName, (XtArgVal) icon); i++;
7077 XtSetArg(args[i], XtNtitle, (XtArgVal) title); i++;
7078 XtSetValues(shellWidget, args, i);
7082 void DisplayError(message, error)
7089 if (appData.debugMode || appData.matchMode) {
7090 fprintf(stderr, "%s: %s\n", programName, message);
7093 if (appData.debugMode || appData.matchMode) {
7094 fprintf(stderr, "%s: %s: %s\n",
7095 programName, message, strerror(error));
7097 snprintf(buf, sizeof(buf), "%s: %s", message, strerror(error));
7100 ErrorPopUp(_("Error"), message, FALSE);
7104 void DisplayMoveError(message)
7109 DrawPosition(FALSE, NULL);
7110 if (appData.debugMode || appData.matchMode) {
7111 fprintf(stderr, "%s: %s\n", programName, message);
7113 if (appData.popupMoveErrors) {
7114 ErrorPopUp(_("Error"), message, FALSE);
7116 DisplayMessage(message, "");
7121 void DisplayFatalError(message, error, status)
7127 errorExitStatus = status;
7129 fprintf(stderr, "%s: %s\n", programName, message);
7131 fprintf(stderr, "%s: %s: %s\n",
7132 programName, message, strerror(error));
7133 snprintf(buf, sizeof(buf), "%s: %s", message, strerror(error));
7136 if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
7137 ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
7143 void DisplayInformation(message)
7147 ErrorPopUp(_("Information"), message, TRUE);
7150 void DisplayNote(message)
7154 ErrorPopUp(_("Note"), message, FALSE);
7158 NullXErrorCheck(dpy, error_event)
7160 XErrorEvent *error_event;
7165 void DisplayIcsInteractionTitle(message)
7168 if (oldICSInteractionTitle == NULL) {
7169 /* Magic to find the old window title, adapted from vim */
7170 char *wina = getenv("WINDOWID");
7172 Window win = (Window) atoi(wina);
7173 Window root, parent, *children;
7174 unsigned int nchildren;
7175 int (*oldHandler)() = XSetErrorHandler(NullXErrorCheck);
7177 if (XFetchName(xDisplay, win, &oldICSInteractionTitle)) break;
7178 if (!XQueryTree(xDisplay, win, &root, &parent,
7179 &children, &nchildren)) break;
7180 if (children) XFree((void *)children);
7181 if (parent == root || parent == 0) break;
7184 XSetErrorHandler(oldHandler);
7186 if (oldICSInteractionTitle == NULL) {
7187 oldICSInteractionTitle = "xterm";
7190 printf("\033]0;%s\007", message);
7194 char pendingReplyPrefix[MSG_SIZ];
7195 ProcRef pendingReplyPR;
7197 void AskQuestionProc(w, event, prms, nprms)
7204 fprintf(stderr, _("AskQuestionProc needed 4 parameters, got %d\n"),
7208 AskQuestionEvent(prms[0], prms[1], prms[2], prms[3]);
7211 void AskQuestionPopDown()
7213 if (!askQuestionUp) return;
7214 XtPopdown(askQuestionShell);
7215 XtDestroyWidget(askQuestionShell);
7216 askQuestionUp = False;
7219 void AskQuestionReplyAction(w, event, prms, nprms)
7229 reply = XawDialogGetValueString(w = XtParent(w));
7230 strcpy(buf, pendingReplyPrefix);
7231 if (*buf) strcat(buf, " ");
7234 OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
7235 AskQuestionPopDown();
7237 if (err) DisplayFatalError(_("Error writing to chess program"), err, 0);
7240 void AskQuestionCallback(w, client_data, call_data)
7242 XtPointer client_data, call_data;
7247 XtSetArg(args[0], XtNlabel, &name);
7248 XtGetValues(w, args, 1);
7250 if (strcmp(name, _("cancel")) == 0) {
7251 AskQuestionPopDown();
7253 AskQuestionReplyAction(w, NULL, NULL, NULL);
7257 void AskQuestion(title, question, replyPrefix, pr)
7258 char *title, *question, *replyPrefix;
7262 Widget popup, layout, dialog, edit;
7268 strcpy(pendingReplyPrefix, replyPrefix);
7269 pendingReplyPR = pr;
7272 XtSetArg(args[i], XtNresizable, True); i++;
7273 XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
7274 askQuestionShell = popup =
7275 XtCreatePopupShell(title, transientShellWidgetClass,
7276 shellWidget, args, i);
7279 XtCreateManagedWidget(layoutName, formWidgetClass, popup,
7280 layoutArgs, XtNumber(layoutArgs));
7283 XtSetArg(args[i], XtNlabel, question); i++;
7284 XtSetArg(args[i], XtNvalue, ""); i++;
7285 XtSetArg(args[i], XtNborderWidth, 0); i++;
7286 dialog = XtCreateManagedWidget("question", dialogWidgetClass,
7289 XawDialogAddButton(dialog, _("enter"), AskQuestionCallback,
7290 (XtPointer) dialog);
7291 XawDialogAddButton(dialog, _("cancel"), AskQuestionCallback,
7292 (XtPointer) dialog);
7294 XtRealizeWidget(popup);
7295 CatchDeleteWindow(popup, "AskQuestionPopDown");
7297 XQueryPointer(xDisplay, xBoardWindow, &root, &child,
7298 &x, &y, &win_x, &win_y, &mask);
7300 XtSetArg(args[0], XtNx, x - 10);
7301 XtSetArg(args[1], XtNy, y - 30);
7302 XtSetValues(popup, args, 2);
7304 XtPopup(popup, XtGrabExclusive);
7305 askQuestionUp = True;
7307 edit = XtNameToWidget(dialog, "*value");
7308 XtSetKeyboardFocus(popup, edit);
7316 if (*name == NULLCHAR) {
7318 } else if (strcmp(name, "$") == 0) {
7319 putc(BELLCHAR, stderr);
7322 snprintf(buf, sizeof(buf), "%s '%s' &", appData.soundProgram, name);
7330 PlaySound(appData.soundMove);
7336 PlaySound(appData.soundIcsWin);
7342 PlaySound(appData.soundIcsLoss);
7348 PlaySound(appData.soundIcsDraw);
7352 PlayIcsUnfinishedSound()
7354 PlaySound(appData.soundIcsUnfinished);
7360 PlaySound(appData.soundIcsAlarm);
7366 system("stty echo");
7372 system("stty -echo");
7376 Colorize(cc, continuation)
7381 int count, outCount, error;
7383 if (textColors[(int)cc].bg > 0) {
7384 if (textColors[(int)cc].fg > 0) {
7385 sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
7386 textColors[(int)cc].fg, textColors[(int)cc].bg);
7388 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
7389 textColors[(int)cc].bg);
7392 if (textColors[(int)cc].fg > 0) {
7393 sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
7394 textColors[(int)cc].fg);
7396 sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);
7399 count = strlen(buf);
7400 outCount = OutputToProcess(NoProc, buf, count, &error);
7401 if (outCount < count) {
7402 DisplayFatalError(_("Error writing to display"), error, 1);
7405 if (continuation) return;
7408 PlaySound(appData.soundShout);
7411 PlaySound(appData.soundSShout);
7414 PlaySound(appData.soundChannel1);
7417 PlaySound(appData.soundChannel);
7420 PlaySound(appData.soundKibitz);
7423 PlaySound(appData.soundTell);
7425 case ColorChallenge:
7426 PlaySound(appData.soundChallenge);
7429 PlaySound(appData.soundRequest);
7432 PlaySound(appData.soundSeek);
7443 return getpwuid(getuid())->pw_name;
7446 static char *ExpandPathName(path)
7449 static char static_buf[2000];
7450 char *d, *s, buf[2000];
7456 while (*s && isspace(*s))
7465 if (*(s+1) == '/') {
7466 strcpy(d, getpwuid(getuid())->pw_dir);
7471 *strchr(buf, '/') = 0;
7472 pwd = getpwnam(buf);
7475 fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
7479 strcpy(d, pwd->pw_dir);
7480 strcat(d, strchr(s+1, '/'));
7491 static char host_name[MSG_SIZ];
7493 #if HAVE_GETHOSTNAME
7494 gethostname(host_name, MSG_SIZ);
7496 #else /* not HAVE_GETHOSTNAME */
7497 # if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
7498 sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
7500 # else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
7502 # endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
7503 #endif /* not HAVE_GETHOSTNAME */
7506 XtIntervalId delayedEventTimerXID = 0;
7507 DelayedEventCallback delayedEventCallback = 0;
7512 delayedEventTimerXID = 0;
7513 delayedEventCallback();
7517 ScheduleDelayedEvent(cb, millisec)
7518 DelayedEventCallback cb; long millisec;
7520 delayedEventCallback = cb;
7521 delayedEventTimerXID =
7522 XtAppAddTimeOut(appContext, millisec,
7523 (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0);
7526 DelayedEventCallback
7529 if (delayedEventTimerXID) {
7530 return delayedEventCallback;
7537 CancelDelayedEvent()
7539 if (delayedEventTimerXID) {
7540 XtRemoveTimeOut(delayedEventTimerXID);
7541 delayedEventTimerXID = 0;
7545 XtIntervalId loadGameTimerXID = 0;
7547 int LoadGameTimerRunning()
7549 return loadGameTimerXID != 0;
7552 int StopLoadGameTimer()
7554 if (loadGameTimerXID != 0) {
7555 XtRemoveTimeOut(loadGameTimerXID);
7556 loadGameTimerXID = 0;
7564 LoadGameTimerCallback(arg, id)
7568 loadGameTimerXID = 0;
7573 StartLoadGameTimer(millisec)
7577 XtAppAddTimeOut(appContext, millisec,
7578 (XtTimerCallbackProc) LoadGameTimerCallback,
7582 XtIntervalId analysisClockXID = 0;
7585 AnalysisClockCallback(arg, id)
7589 if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
7590 || appData.icsEngineAnalyze) { // [DM]
7591 AnalysisPeriodicEvent(0);
7592 StartAnalysisClock();
7597 StartAnalysisClock()
7600 XtAppAddTimeOut(appContext, 2000,
7601 (XtTimerCallbackProc) AnalysisClockCallback,
7605 gint clockTimerTag = 0;
7607 int ClockTimerRunning()
7609 return clockTimerTag != 0;
7612 int StopClockTimer()
7614 if (clockTimerTag != 0) {
7615 gtk_timeout_remove(clockTimerTag);
7624 ClockTimerCallback(data)
7633 StartClockTimer(millisec)
7636 clockTimerTag = gtk_timeout_add(millisec,(GtkFunction) ClockTimerCallback,NULL);
7641 DisplayTimerLabel(w, color, timer, highlight)
7650 if (appData.clockMode) {
7651 sprintf(buf, "%s: %s", color, TimeString(timer));
7653 sprintf(buf, "%s ", color);
7655 gtk_label_set_text(GTK_LABEL(w),buf);
7657 /* check for low time warning */
7658 // Pixel foregroundOrWarningColor = timerForegroundPixel;
7661 // appData.lowTimeWarning &&
7662 // (timer / 1000) < appData.icsAlarmTime)
7663 // foregroundOrWarningColor = lowTimeWarningColor;
7665 // if (appData.clockMode) {
7666 // sprintf(buf, "%s: %s", color, TimeString(timer));
7667 // XtSetArg(args[0], XtNlabel, buf);
7669 // sprintf(buf, "%s ", color);
7670 // XtSetArg(args[0], XtNlabel, buf);
7675 // XtSetArg(args[1], XtNbackground, foregroundOrWarningColor);
7676 // XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
7678 // XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
7679 // XtSetArg(args[2], XtNforeground, foregroundOrWarningColor);
7682 // XtSetValues(w, args, 3);
7687 DisplayWhiteClock(timeRemaining, highlight)
7691 if(appData.noGUI) return;
7693 DisplayTimerLabel(GUI_Whiteclock, _("White"), timeRemaining, highlight);
7694 if (highlight && WindowIcon == BlackIcon) {
7695 WindowIcon = WhiteIcon;
7696 gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
7701 DisplayBlackClock(timeRemaining, highlight)
7705 if(appData.noGUI) return;
7706 DisplayTimerLabel(GUI_Blackclock, _("Black"), timeRemaining, highlight);
7707 if (highlight && WindowIcon == WhiteIcon) {
7708 WindowIcon = BlackIcon;
7709 gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
7727 int StartChildProcess(cmdLine, dir, pr)
7734 int to_prog[2], from_prog[2];
7738 if (appData.debugMode) {
7739 fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
7742 /* We do NOT feed the cmdLine to the shell; we just
7743 parse it into blank-separated arguments in the
7744 most simple-minded way possible.
7747 strcpy(buf, cmdLine);
7752 if (p == NULL) break;
7757 SetUpChildIO(to_prog, from_prog);
7759 if ((pid = fork()) == 0) {
7761 // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1
7762 close(to_prog[1]); // first close the unused pipe ends
7763 close(from_prog[0]);
7764 dup2(to_prog[0], 0); // to_prog was created first, nd is the only one to use 0 or 1
7765 dup2(from_prog[1], 1);
7766 if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original
7767 close(from_prog[1]); // and closing again loses one of the pipes!
7768 if(fileno(stderr) >= 2) // better safe than sorry...
7769 dup2(1, fileno(stderr)); /* force stderr to the pipe */
7771 if (dir[0] != NULLCHAR && chdir(dir) != 0) {
7776 nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc
7778 execvp(argv[0], argv);
7780 /* If we get here, exec failed */
7785 /* Parent process */
7787 close(from_prog[1]);
7789 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
7792 cp->fdFrom = from_prog[0];
7793 cp->fdTo = to_prog[1];
7798 // [HGM] kill: implement the 'hard killing' of AS's Winboard_x
7799 static RETSIGTYPE AlarmCallBack(int n)
7805 DestroyChildProcess(pr, signalType)
7809 ChildProc *cp = (ChildProc *) pr;
7811 if (cp->kind != CPReal) return;
7813 if (signalType == 10) { // [HGM] kill: if it does not terminate in 3 sec, kill
7814 signal(SIGALRM, AlarmCallBack);
7816 if(wait((int *) 0) == -1) { // process does not terminate on its own accord
7817 kill(cp->pid, SIGKILL); // kill it forcefully
7818 wait((int *) 0); // and wait again
7822 kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: use hard kill if so requested
7824 /* Process is exiting either because of the kill or because of
7825 a quit command sent by the backend; either way, wait for it to die.
7834 InterruptChildProcess(pr)
7837 ChildProc *cp = (ChildProc *) pr;
7839 if (cp->kind != CPReal) return;
7840 (void) kill(cp->pid, SIGINT); /* stop it thinking */
7843 int OpenTelnet(host, port, pr)
7848 char cmdLine[MSG_SIZ];
7850 if (port[0] == NULLCHAR) {
7851 snprintf(cmdLine, sizeof(cmdLine), "%s %s", appData.telnetProgram, host);
7853 snprintf(cmdLine, sizeof(cmdLine), "%s %s %s", appData.telnetProgram, host, port);
7855 return StartChildProcess(cmdLine, "", pr);
7858 int OpenTCP(host, port, pr)
7864 DisplayFatalError(_("Socket support is not configured in"), 0, 2);
7865 #else /* !OMIT_SOCKETS */
7867 struct sockaddr_in sa;
7869 unsigned short uport;
7872 if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
7876 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
7877 sa.sin_family = AF_INET;
7878 sa.sin_addr.s_addr = INADDR_ANY;
7879 uport = (unsigned short) 0;
7880 sa.sin_port = htons(uport);
7881 if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
7885 memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
7886 if (!(hp = gethostbyname(host))) {
7888 if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
7889 hp = (struct hostent *) calloc(1, sizeof(struct hostent));
7890 hp->h_addrtype = AF_INET;
7892 hp->h_addr_list = (char **) calloc(2, sizeof(char *));
7893 hp->h_addr_list[0] = (char *) malloc(4);
7894 hp->h_addr_list[0][0] = b0;
7895 hp->h_addr_list[0][1] = b1;
7896 hp->h_addr_list[0][2] = b2;
7897 hp->h_addr_list[0][3] = b3;
7902 sa.sin_family = hp->h_addrtype;
7903 uport = (unsigned short) atoi(port);
7904 sa.sin_port = htons(uport);
7905 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
7907 if (connect(s, (struct sockaddr *) &sa,
7908 sizeof(struct sockaddr_in)) < 0) {
7912 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
7919 #endif /* !OMIT_SOCKETS */
7924 int OpenCommPort(name, pr)
7931 fd = open(name, 2, 0);
7932 if (fd < 0) return errno;
7934 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
7944 int OpenLoopback(pr)
7950 SetUpChildIO(to, from);
7952 cp = (ChildProc *) calloc(1, sizeof(ChildProc));
7955 cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */
7962 int OpenRcmd(host, user, cmd, pr)
7963 char *host, *user, *cmd;
7966 DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
7970 #define INPUT_SOURCE_BUF_SIZE 8192
7979 char buf[INPUT_SOURCE_BUF_SIZE];
7984 DoInputCallback(closure, source, xid)
7989 InputSource *is = (InputSource *) closure;
7994 if (is->lineByLine) {
7995 count = read(is->fd, is->unused,
7996 INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
7998 (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
8001 is->unused += count;
8003 while (p < is->unused) {
8004 q = memchr(p, '\n', is->unused - p);
8005 if (q == NULL) break;
8007 (is->func)(is, is->closure, p, q - p, 0);
8011 while (p < is->unused) {
8016 count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
8021 (is->func)(is, is->closure, is->buf, count, error);
8025 InputSourceRef AddInputSource(pr, lineByLine, func, closure)
8032 ChildProc *cp = (ChildProc *) pr;
8034 is = (InputSource *) calloc(1, sizeof(InputSource));
8035 is->lineByLine = lineByLine;
8039 is->fd = fileno(stdin);
8041 is->kind = cp->kind;
8042 is->fd = cp->fdFrom;
8045 is->unused = is->buf;
8048 is->xid = XtAppAddInput(appContext, is->fd,
8049 (XtPointer) (XtInputReadMask),
8050 (XtInputCallbackProc) DoInputCallback,
8052 is->closure = closure;
8053 return (InputSourceRef) is;
8057 RemoveInputSource(isr)
8060 InputSource *is = (InputSource *) isr;
8062 if (is->xid == 0) return;
8063 XtRemoveInput(is->xid);
8067 int OutputToProcess(pr, message, count, outError)
8073 ChildProc *cp = (ChildProc *) pr;
8077 outCount = fwrite(message, 1, count, stdout);
8079 outCount = write(cp->fdTo, message, count);
8089 /* Output message to process, with "ms" milliseconds of delay
8090 between each character. This is needed when sending the logon
8091 script to ICC, which for some reason doesn't like the
8092 instantaneous send. */
8093 int OutputToProcessDelayed(pr, message, count, outError, msdelay)
8100 ChildProc *cp = (ChildProc *) pr;
8105 r = write(cp->fdTo, message++, 1);
8118 /**** Animation code by Hugh Fisher, DCS, ANU.
8120 Known problem: if a window overlapping the board is
8121 moved away while a piece is being animated underneath,
8122 the newly exposed area won't be updated properly.
8123 I can live with this.
8125 Known problem: if you look carefully at the animation
8126 of pieces in mono mode, they are being drawn as solid
8127 shapes without interior detail while moving. Fixing
8128 this would be a major complication for minimal return.
8131 /* Masks for XPM pieces. Black and white pieces can have
8132 different shapes, but in the interest of retaining my
8133 sanity pieces must have the same outline on both light
8134 and dark squares, and all pieces must use the same
8135 background square colors/images. */
8137 static int xpmDone = 0;
8140 CreateAnimMasks (pieceDepth)
8147 unsigned long plane;
8150 /* Need a bitmap just to get a GC with right depth */
8151 buf = XCreatePixmap(xDisplay, xBoardWindow,
8153 values.foreground = 1;
8154 values.background = 0;
8155 /* Don't use XtGetGC, not read only */
8156 maskGC = XCreateGC(xDisplay, buf,
8157 GCForeground | GCBackground, &values);
8158 XFreePixmap(xDisplay, buf);
8160 buf = XCreatePixmap(xDisplay, xBoardWindow,
8161 squareSize, squareSize, pieceDepth);
8162 values.foreground = XBlackPixel(xDisplay, xScreen);
8163 values.background = XWhitePixel(xDisplay, xScreen);
8164 bufGC = XCreateGC(xDisplay, buf,
8165 GCForeground | GCBackground, &values);
8167 for (piece = WhitePawn; piece <= BlackKing; piece++) {
8168 /* Begin with empty mask */
8169 if(!xpmDone) // [HGM] pieces: keep using existing
8170 xpmMask[piece] = XCreatePixmap(xDisplay, xBoardWindow,
8171 squareSize, squareSize, 1);
8172 XSetFunction(xDisplay, maskGC, GXclear);
8173 XFillRectangle(xDisplay, xpmMask[piece], maskGC,
8174 0, 0, squareSize, squareSize);
8176 /* Take a copy of the piece */
8181 XSetFunction(xDisplay, bufGC, GXcopy);
8182 XCopyArea(xDisplay, xpmPieceBitmap[kind][((int)piece) % (int)BlackPawn],
8184 0, 0, squareSize, squareSize, 0, 0);
8186 /* XOR the background (light) over the piece */
8187 XSetFunction(xDisplay, bufGC, GXxor);
8189 XCopyArea(xDisplay, xpmLightSquare, buf, bufGC,
8190 0, 0, squareSize, squareSize, 0, 0);
8192 XSetForeground(xDisplay, bufGC, lightSquareColor);
8193 XFillRectangle(xDisplay, buf, bufGC, 0, 0, squareSize, squareSize);
8196 /* We now have an inverted piece image with the background
8197 erased. Construct mask by just selecting all the non-zero
8198 pixels - no need to reconstruct the original image. */
8199 XSetFunction(xDisplay, maskGC, GXor);
8201 /* Might be quicker to download an XImage and create bitmap
8202 data from it rather than this N copies per piece, but it
8203 only takes a fraction of a second and there is a much
8204 longer delay for loading the pieces. */
8205 for (n = 0; n < pieceDepth; n ++) {
8206 XCopyPlane(xDisplay, buf, xpmMask[piece], maskGC,
8207 0, 0, squareSize, squareSize,
8213 XFreePixmap(xDisplay, buf);
8214 XFreeGC(xDisplay, bufGC);
8215 XFreeGC(xDisplay, maskGC);
8219 InitAnimState (anim, info)
8221 XWindowAttributes * info;
8226 /* Each buffer is square size, same depth as window */
8227 anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow,
8228 squareSize, squareSize, info->depth);
8229 anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow,
8230 squareSize, squareSize, info->depth);
8232 /* Create a plain GC for blitting */
8233 mask = GCForeground | GCBackground | GCFunction |
8234 GCPlaneMask | GCGraphicsExposures;
8235 values.foreground = XBlackPixel(xDisplay, xScreen);
8236 values.background = XWhitePixel(xDisplay, xScreen);
8237 values.function = GXcopy;
8238 values.plane_mask = AllPlanes;
8239 values.graphics_exposures = False;
8240 anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values);
8242 /* Piece will be copied from an existing context at
8243 the start of each new animation/drag. */
8244 anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values);
8246 /* Outline will be a read-only copy of an existing */
8247 anim->outlineGC = None;
8253 static VariantClass old = (VariantClass) -1; // [HGM] pieces: redo every time variant changes
8254 XWindowAttributes info;
8256 if (xpmDone && gameInfo.variant == old) return;
8257 if(xpmDone) old = gameInfo.variant; // first time pieces might not be created yet
8258 // XGetWindowAttributes(xDisplay, xBoardWindow, &info);
8260 InitAnimState(&game, &info);
8261 InitAnimState(&player, &info);
8263 /* For XPM pieces, we need bitmaps to use as masks. */
8265 CreateAnimMasks(info.depth);
8271 static Boolean frameWaiting;
8273 static RETSIGTYPE FrameAlarm (sig)
8276 frameWaiting = False;
8277 /* In case System-V style signals. Needed?? */
8278 signal(SIGALRM, FrameAlarm);
8285 struct itimerval delay;
8287 XSync(xDisplay, False);
8290 frameWaiting = True;
8291 signal(SIGALRM, FrameAlarm);
8292 delay.it_interval.tv_sec =
8293 delay.it_value.tv_sec = time / 1000;
8294 delay.it_interval.tv_usec =
8295 delay.it_value.tv_usec = (time % 1000) * 1000;
8296 setitimer(ITIMER_REAL, &delay, NULL);
8298 /* Ugh -- busy-wait! --tpm */
8299 while (frameWaiting);
8301 while (frameWaiting) pause();
8303 delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
8304 delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
8305 setitimer(ITIMER_REAL, &delay, NULL);
8315 XSync(xDisplay, False);
8317 usleep(time * 1000);
8322 /* Convert board position to corner of screen rect and color */
8325 ScreenSquare(column, row, pt, color)
8326 int column; int row; XPoint * pt; int * color;
8329 pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);
8330 pt->y = lineGap + row * (squareSize + lineGap);
8332 pt->x = lineGap + column * (squareSize + lineGap);
8333 pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);
8335 *color = SquareColor(row, column);
8338 /* Convert window coords to square */
8341 BoardSquare(x, y, column, row)
8342 int x; int y; int * column; int * row;
8344 *column = EventToSquare(x, BOARD_WIDTH);
8345 if (flipView && *column >= 0)
8346 *column = BOARD_WIDTH - 1 - *column;
8347 *row = EventToSquare(y, BOARD_HEIGHT);
8348 if (!flipView && *row >= 0)
8349 *row = BOARD_HEIGHT - 1 - *row;
8354 #undef Max /* just in case */
8356 #define Max(a, b) ((a) > (b) ? (a) : (b))
8357 #define Min(a, b) ((a) < (b) ? (a) : (b))
8360 SetRect(rect, x, y, width, height)
8361 XRectangle * rect; int x; int y; int width; int height;
8365 rect->width = width;
8366 rect->height = height;
8369 /* Test if two frames overlap. If they do, return
8370 intersection rect within old and location of
8371 that rect within new. */
8374 Intersect(old, new, size, area, pt)
8375 XPoint * old; XPoint * new;
8376 int size; XRectangle * area; XPoint * pt;
8378 if (old->x > new->x + size || new->x > old->x + size ||
8379 old->y > new->y + size || new->y > old->y + size) {
8382 SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0),
8383 size - abs(old->x - new->x), size - abs(old->y - new->y));
8384 pt->x = Max(old->x - new->x, 0);
8385 pt->y = Max(old->y - new->y, 0);
8390 /* For two overlapping frames, return the rect(s)
8391 in the old that do not intersect with the new. */
8394 CalcUpdateRects(old, new, size, update, nUpdates)
8395 XPoint * old; XPoint * new; int size;
8396 XRectangle update[]; int * nUpdates;
8400 /* If old = new (shouldn't happen) then nothing to draw */
8401 if (old->x == new->x && old->y == new->y) {
8405 /* Work out what bits overlap. Since we know the rects
8406 are the same size we don't need a full intersect calc. */
8408 /* Top or bottom edge? */
8409 if (new->y > old->y) {
8410 SetRect(&(update[count]), old->x, old->y, size, new->y - old->y);
8412 } else if (old->y > new->y) {
8413 SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y),
8414 size, old->y - new->y);
8417 /* Left or right edge - don't overlap any update calculated above. */
8418 if (new->x > old->x) {
8419 SetRect(&(update[count]), old->x, Max(new->y, old->y),
8420 new->x - old->x, size - abs(new->y - old->y));
8422 } else if (old->x > new->x) {
8423 SetRect(&(update[count]), new->x + size, Max(new->y, old->y),
8424 old->x - new->x, size - abs(new->y - old->y));
8431 /* Generate a series of frame coords from start->mid->finish.
8432 The movement rate doubles until the half way point is
8433 reached, then halves back down to the final destination,
8434 which gives a nice slow in/out effect. The algorithmn
8435 may seem to generate too many intermediates for short
8436 moves, but remember that the purpose is to attract the
8437 viewers attention to the piece about to be moved and
8438 then to where it ends up. Too few frames would be less
8442 Tween(start, mid, finish, factor, frames, nFrames)
8443 XPoint * start; XPoint * mid;
8444 XPoint * finish; int factor;
8445 XPoint frames[]; int * nFrames;
8447 int fraction, n, count;
8451 /* Slow in, stepping 1/16th, then 1/8th, ... */
8453 for (n = 0; n < factor; n++)
8455 for (n = 0; n < factor; n++) {
8456 frames[count].x = start->x + (mid->x - start->x) / fraction;
8457 frames[count].y = start->y + (mid->y - start->y) / fraction;
8459 fraction = fraction / 2;
8463 frames[count] = *mid;
8466 /* Slow out, stepping 1/2, then 1/4, ... */
8468 for (n = 0; n < factor; n++) {
8469 frames[count].x = finish->x - (finish->x - mid->x) / fraction;
8470 frames[count].y = finish->y - (finish->y - mid->y) / fraction;
8472 fraction = fraction * 2;
8477 /* Draw a piece on the screen without disturbing what's there */
8480 SelectGCMask(piece, clip, outline, mask)
8481 ChessSquare piece; GC * clip; GC * outline; Pixmap * mask;
8485 /* Bitmap for piece being moved. */
8486 if (appData.monoMode) {
8487 *mask = *pieceToSolid(piece);
8488 } else if (useImages) {
8490 *mask = xpmMask[piece];
8492 *mask = ximMaskPm[piece];
8495 *mask = *pieceToSolid(piece);
8498 /* GC for piece being moved. Square color doesn't matter, but
8499 since it gets modified we make a copy of the original. */
8501 if (appData.monoMode)
8506 if (appData.monoMode)
8511 XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
8513 /* Outline only used in mono mode and is not modified */
8515 *outline = bwPieceGC;
8517 *outline = wbPieceGC;
8521 OverlayPiece(piece, clip, outline, dest)
8522 ChessSquare piece; GC clip; GC outline; Drawable dest;
8527 /* Draw solid rectangle which will be clipped to shape of piece */
8528 XFillRectangle(xDisplay, dest, clip,
8529 0, 0, squareSize, squareSize);
8530 if (appData.monoMode)
8531 /* Also draw outline in contrasting color for black
8532 on black / white on white cases */
8533 XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
8534 0, 0, squareSize, squareSize, 0, 0, 1);
8536 /* Copy the piece */
8541 XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
8543 0, 0, squareSize, squareSize,
8548 /* Animate the movement of a single piece */
8551 BeginAnimation(anim, piece, startColor, start)
8559 /* The old buffer is initialised with the start square (empty) */
8560 BlankSquare(0, 0, startColor, EmptySquare, anim->saveBuf);
8561 anim->prevFrame = *start;
8563 /* The piece will be drawn using its own bitmap as a matte */
8564 SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
8565 XSetClipMask(xDisplay, anim->pieceGC, mask);
8569 AnimationFrame(anim, frame, piece)
8574 XRectangle updates[4];
8579 /* Save what we are about to draw into the new buffer */
8580 XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC,
8581 frame->x, frame->y, squareSize, squareSize,
8584 /* Erase bits of the previous frame */
8585 if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) {
8586 /* Where the new frame overlapped the previous,
8587 the contents in newBuf are wrong. */
8588 XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC,
8589 overlap.x, overlap.y,
8590 overlap.width, overlap.height,
8592 /* Repaint the areas in the old that don't overlap new */
8593 CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count);
8594 for (i = 0; i < count; i++)
8595 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
8596 updates[i].x - anim->prevFrame.x,
8597 updates[i].y - anim->prevFrame.y,
8598 updates[i].width, updates[i].height,
8599 updates[i].x, updates[i].y);
8601 /* Easy when no overlap */
8602 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
8603 0, 0, squareSize, squareSize,
8604 anim->prevFrame.x, anim->prevFrame.y);
8607 /* Save this frame for next time round */
8608 XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC,
8609 0, 0, squareSize, squareSize,
8611 anim->prevFrame = *frame;
8613 /* Draw piece over original screen contents, not current,
8614 and copy entire rect. Wipes out overlapping piece images. */
8615 OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf);
8616 XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
8617 0, 0, squareSize, squareSize,
8618 frame->x, frame->y);
8622 EndAnimation (anim, finish)
8626 XRectangle updates[4];
8631 /* The main code will redraw the final square, so we
8632 only need to erase the bits that don't overlap. */
8633 if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) {
8634 CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count);
8635 for (i = 0; i < count; i++)
8636 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
8637 updates[i].x - anim->prevFrame.x,
8638 updates[i].y - anim->prevFrame.y,
8639 updates[i].width, updates[i].height,
8640 updates[i].x, updates[i].y);
8642 XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
8643 0, 0, squareSize, squareSize,
8644 anim->prevFrame.x, anim->prevFrame.y);
8649 FrameSequence(anim, piece, startColor, start, finish, frames, nFrames)
8651 ChessSquare piece; int startColor;
8652 XPoint * start; XPoint * finish;
8653 XPoint frames[]; int nFrames;
8657 BeginAnimation(anim, piece, startColor, start);
8658 for (n = 0; n < nFrames; n++) {
8659 AnimationFrame(anim, &(frames[n]), piece);
8660 FrameDelay(appData.animSpeed);
8662 EndAnimation(anim, finish);
8665 /* Main control logic for deciding what to animate and how */
8668 AnimateMove(board, fromX, fromY, toX, toY)
8677 XPoint start, finish, mid;
8678 XPoint frames[kFactor * 2 + 1];
8679 int nFrames, startColor, endColor;
8681 /* Are we animating? */
8682 if (!appData.animate || appData.blindfold)
8685 if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing ||
8686 board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing)
8687 return; // [HGM] FRC: no animtion of FRC castlings, as to-square is not true to-square
8689 if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
8690 piece = board[fromY][fromX];
8691 if (piece >= EmptySquare) return;
8696 hop = (piece == WhiteKnight || piece == BlackKnight);
8699 if (appData.debugMode) {
8700 fprintf(debugFP, hop ? _("AnimateMove: piece %d hops from %d,%d to %d,%d \n") :
8701 _("AnimateMove: piece %d slides from %d,%d to %d,%d \n"),
8702 piece, fromX, fromY, toX, toY); }
8704 ScreenSquare(fromX, fromY, &start, &startColor);
8705 ScreenSquare(toX, toY, &finish, &endColor);
8708 /* Knight: make diagonal movement then straight */
8709 if (abs(toY - fromY) < abs(toX - fromX)) {
8710 mid.x = start.x + (finish.x - start.x) / 2;
8714 mid.y = start.y + (finish.y - start.y) / 2;
8717 mid.x = start.x + (finish.x - start.x) / 2;
8718 mid.y = start.y + (finish.y - start.y) / 2;
8721 /* Don't use as many frames for very short moves */
8722 if (abs(toY - fromY) + abs(toX - fromX) <= 2)
8723 Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);
8725 Tween(&start, &mid, &finish, kFactor, frames, &nFrames);
8726 FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
8728 /* Be sure end square is redrawn */
8729 damage[toY][toX] = True;
8733 DragPieceBegin(x, y)
8736 int boardX, boardY, color;
8739 /* Are we animating? */
8740 if (!appData.animateDragging || appData.blindfold)
8743 /* Figure out which square we start in and the
8744 mouse position relative to top left corner. */
8745 BoardSquare(x, y, &boardX, &boardY);
8746 player.startBoardX = boardX;
8747 player.startBoardY = boardY;
8748 ScreenSquare(boardX, boardY, &corner, &color);
8749 player.startSquare = corner;
8750 player.startColor = color;
8752 /* Start from exactly where the piece is. This can be confusing
8753 if you start dragging far from the center of the square; most
8754 or all of the piece can be over a different square from the one
8755 the mouse pointer is in. */
8756 player.mouseDelta.x = x - corner.x;
8757 player.mouseDelta.y = y - corner.y;
8759 /* As soon as we start dragging, the piece will jump slightly to
8760 be centered over the mouse pointer. */
8761 player.mouseDelta.x = squareSize/2;
8762 player.mouseDelta.y = squareSize/2;
8764 /* Initialise animation */
8765 player.dragPiece = PieceForSquare(boardX, boardY);
8767 if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {
8768 player.dragActive = True;
8769 BeginAnimation(&player, player.dragPiece, color, &corner);
8770 /* Mark this square as needing to be redrawn. Note that
8771 we don't remove the piece though, since logically (ie
8772 as seen by opponent) the move hasn't been made yet. */
8773 if(boardX == BOARD_RGHT+1 && PieceForSquare(boardX-1, boardY) > 1 ||
8774 boardX == BOARD_LEFT-2 && PieceForSquare(boardX+1, boardY) > 1)
8775 XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC,
8776 corner.x, corner.y, squareSize, squareSize,
8777 0, 0); // [HGM] zh: unstack in stead of grab
8778 damage[boardY][boardX] = True;
8780 player.dragActive = False;
8790 /* Are we animating? */
8791 if (!appData.animateDragging || appData.blindfold)
8795 if (! player.dragActive)
8797 /* Move piece, maintaining same relative position
8798 of mouse within square */
8799 corner.x = x - player.mouseDelta.x;
8800 corner.y = y - player.mouseDelta.y;
8801 AnimationFrame(&player, &corner, player.dragPiece);
8803 if (appData.highlightDragging) {
8805 BoardSquare(x, y, &boardX, &boardY);
8806 SetHighlights(fromX, fromY, boardX, boardY);
8815 int boardX, boardY, color;
8818 /* Are we animating? */
8819 if (!appData.animateDragging || appData.blindfold)
8823 if (! player.dragActive)
8825 /* Last frame in sequence is square piece is
8826 placed on, which may not match mouse exactly. */
8827 BoardSquare(x, y, &boardX, &boardY);
8828 ScreenSquare(boardX, boardY, &corner, &color);
8829 EndAnimation(&player, &corner);
8831 /* Be sure end square is redrawn */
8832 damage[boardY][boardX] = True;
8834 /* This prevents weird things happening with fast successive
8835 clicks which on my Sun at least can cause motion events
8836 without corresponding press/release. */
8837 player.dragActive = False;
8840 /* Handle expose event while piece being dragged */
8845 if (!player.dragActive || appData.blindfold)
8848 /* What we're doing: logically, the move hasn't been made yet,
8849 so the piece is still in it's original square. But visually
8850 it's being dragged around the board. So we erase the square
8851 that the piece is on and draw it at the last known drag point. */
8852 BlankSquare(player.startSquare.x, player.startSquare.y,
8853 player.startColor, EmptySquare, xBoardWindow);
8854 AnimationFrame(&player, &player.prevFrame, player.dragPiece);
8855 damage[player.startBoardY][player.startBoardX] = TRUE;
8859 SetProgramStats( FrontEndProgramStats * stats )
8862 // [HGM] done, but perhaps backend should call this directly?
8863 EngineOutputUpdate( stats );