X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=0f12af6e9e2c8d2efaf3082bb8f0642bc9fff4a6;hb=c95ef32a700132a134f335f857ca6f1b6f3c169f;hp=55cb8d99aea719c70e17277faca88b5026f7a086;hpb=ba19c79e683860fba8cafa5ca24b0f8191b4c1d5;p=xboard.git diff --git a/xboard.c b/xboard.c index 55cb8d9..0f12af6 100644 --- a/xboard.c +++ b/xboard.c @@ -2,7 +2,7 @@ * xboard.c -- X front end for XBoard * * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. + * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, * 2007, 2008, 2009, 2010 Free Software Foundation, Inc. @@ -141,6 +141,12 @@ extern char *getenv(); # endif #endif + +# if HAVE_LIBREADLINE /* add gnu-readline support */ +#include +#include +# endif + #include #include #include @@ -191,6 +197,7 @@ extern char *getenv(); #include "frontend.h" #include "backend.h" +#include "backendz.h" #include "moves.h" #include "xboard.h" #include "childio.h" @@ -262,6 +269,10 @@ void AnimateUserMove P((Widget w, XEvent * event, String * params, Cardinal * nParams)); void HandlePV P((Widget w, XEvent * event, String * params, Cardinal * nParams)); +void SelectPV P((Widget w, XEvent * event, + String * params, Cardinal * nParams)); +void StopPV P((Widget w, XEvent * event, + String * params, Cardinal * nParams)); void WhiteClock P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BlackClock P((Widget w, XEvent *event, @@ -270,6 +281,8 @@ void DrawPositionProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void XDrawPosition P((Widget w, /*Boolean*/int repaint, Board board)); +void CommentClick P((Widget w, XEvent * event, + String * params, Cardinal * nParams)); void CommentPopUp P((char *title, char *label)); void CommentPopDown P((void)); void CommentCallback P((Widget w, XtPointer client_data, @@ -369,6 +382,7 @@ void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void AnnotateProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void TruncateGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void RetractMoveProc P((Widget w, XEvent *event, String *prms, @@ -460,6 +474,11 @@ void SettingsPopDown P(()); void update_ics_width P(()); int get_term_width P(()); int CopyMemoProc P(()); + +# if HAVE_LIBREADLINE /* add gnu-readline support */ +static void ReadlineCompleteHandler P((char *)); +# endif + /* * XBoard depends on Xt R4 or higher */ @@ -481,6 +500,8 @@ Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget, menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell, ICSInputShell, fileNameShell, askQuestionShell; Widget historyShell, evalGraphShell, gameListShell; +int hOffset; // [HGM] dual +XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2]; XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2]; XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6]; Font clockFontID, coordFontID, countFontID; @@ -493,6 +514,13 @@ FileProc fileProc; char *fileOpenMode; char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion +# if HAVE_LIBREADLINE /* gnu readline support */ +static char* readline_buffer; +static int readline_complete=0; +extern int sending_ICS_login; +extern int sending_ICS_password; +#endif + Position commentX = -1, commentY = -1; Dimension commentW, commentH; typedef unsigned int BoardSize; @@ -657,6 +685,7 @@ MenuItem stepMenu[] = { {N_("Back to Start"), ToStartProc}, {N_("Forward to End"), ToEndProc}, {N_("Revert"), RevertProc}, + {N_("Annotate"), AnnotateProc}, {N_("Truncate Game"), TruncateGameProc}, {"----", NothingProc}, {N_("Move Now"), MoveNowProc}, @@ -742,23 +771,23 @@ MenuItem buttonBar[] = { #define PIECE_MENU_SIZE 18 String pieceMenuStrings[2][PIECE_MENU_SIZE] = { { N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), - N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), - N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), + N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), + N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), N_("Empty square"), N_("Clear board") }, { N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"), - N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), - N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), + N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"), + N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"), N_("Empty square"), N_("Clear board") } }; /* must be in same order as PieceMenuStrings! */ ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = { { WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil, - WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0, + WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0, PromotePiece, DemotePiece, EmptySquare, ClearBoard }, { BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop, BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil, - BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0, + BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0, PromotePiece, DemotePiece, EmptySquare, ClearBoard }, }; @@ -846,7 +875,8 @@ XtActionsRec boardActions[] = { { "HandleUserMove", HandleUserMove }, { "AnimateUserMove", AnimateUserMove }, { "HandlePV", HandlePV }, - { "UnLoadPV", UnLoadPV }, + { "SelectPV", SelectPV }, + { "StopPV", StopPV }, { "FileNameAction", FileNameAction }, { "AskQuestionProc", AskQuestionProc }, { "AskQuestionReplyAction", AskQuestionReplyAction }, @@ -855,6 +885,7 @@ XtActionsRec boardActions[] = { { "BlackClock", BlackClock }, { "Iconify", Iconify }, { "ResetProc", ResetProc }, + { "NewVariantProc", NewVariantProc }, { "LoadGameProc", LoadGameProc }, { "LoadNextGameProc", LoadNextGameProc }, { "LoadPrevGameProc", LoadPrevGameProc }, @@ -914,9 +945,13 @@ XtActionsRec boardActions[] = { { "ToStartProc", ToStartProc }, { "ToEndProc", ToEndProc }, { "RevertProc", RevertProc }, + { "AnnotateProc", AnnotateProc }, { "TruncateGameProc", TruncateGameProc }, { "MoveNowProc", MoveNowProc }, { "RetractMoveProc", RetractMoveProc }, + { "EngineMenuProc", (XtActionProc) EngineMenuProc }, + { "UciMenuProc", (XtActionProc) UciMenuProc }, + { "TimeControlProc", (XtActionProc) TimeControlProc }, { "AlwaysQueenProc", AlwaysQueenProc }, { "AnimateDraggingProc", AnimateDraggingProc }, { "AnimateMovingProc", AnimateMovingProc }, @@ -956,6 +991,7 @@ XtActionsRec boardActions[] = { { "AboutProc", AboutProc }, { "DebugProc", DebugProc }, { "NothingProc", NothingProc }, + { "CommentClick", (XtActionProc) CommentClick }, { "CommentPopDown", (XtActionProc) CommentPopDown }, { "EditCommentPopDown", (XtActionProc) EditCommentPopDown }, { "TagsPopDown", (XtActionProc) TagsPopDown }, @@ -979,26 +1015,64 @@ XtActionsRec boardActions[] = { }; char globalTranslations[] = - ":R: ResignProc() \n \ - :r: ResetProc() \n \ - :g: LoadGameProc() \n \ - :N: LoadNextGameProc() \n \ - :P: LoadPrevGameProc() \n \ - :Q: QuitProc() \n \ - :F: ToEndProc() \n \ - :f: ForwardProc() \n \ - :B: ToStartProc() \n \ - :b: BackwardProc() \n \ - :p: PauseProc() \n \ - :d: DrawProc() \n \ - :t: CallFlagProc() \n \ - :i: Iconify() \n \ - :c: Iconify() \n \ - :v: FlipViewProc() \n \ - Control_L: BackwardProc() \n \ - Control_L: ForwardProc() \n \ - Control_R: BackwardProc() \n \ - Control_R: ForwardProc() \n \ + ":F9: ResignProc() \n \ + :Ctrln: ResetProc() \n \ + :MetaV: NewVariantProc() \n \ + :Ctrlo: LoadGameProc() \n \ + :MetaNext: LoadNextGameProc() \n \ + :MetaPrior: LoadPrevGameProc() \n \ + :Ctrls: SaveGameProc() \n \ + :Ctrlc: CopyGameProc() \n \ + :Ctrlv: PasteGameProc() \n \ + :CtrlO: LoadPositionProc() \n \ + :Shift MetaNext: LoadNextPositionProc() \n \ + :Shift MetaPrior: LoadPrevPositionProc() \n \ + :CtrlS: SavePositionProc() \n \ + :CtrlC: CopyPositionProc() \n \ + :CtrlV: PastePositionProc() \n \ + :Ctrlq: QuitProc() \n \ + :Ctrlw: MachineWhiteProc() \n \ + :Ctrlb: MachineBlackProc() \n \ + :Ctrlt: TwoMachinesProc() \n \ + :Ctrla: AnalysisModeProc() \n \ + :Ctrlf: AnalyzeFileProc() \n \ + :Ctrle: EditGameProc() \n \ + :CtrlE: EditPositionProc() \n \ + :MetaO: EngineOutputProc() \n \ + :MetaE: EvalGraphProc() \n \ + :MetaG: ShowGameListProc() \n \ + :MetaH: ShowMoveListProc() \n \ + :Pause: PauseProc() \n \ + :F3: AcceptProc() \n \ + :F4: DeclineProc() \n \ + :F12: RematchProc() \n \ + :F5: CallFlagProc() \n \ + :F6: DrawProc() \n \ + :F7: AdjournProc() \n \ + :F8: AbortProc() \n \ + :F10: StopObservingProc() \n \ + :F11: StopExaminingProc() \n \ + :Meta CtrlF12: DebugProc() \n \ + :MetaEnd: ToEndProc() \n \ + :MetaRight: ForwardProc() \n \ + :MetaHome: ToStartProc() \n \ + :MetaLeft: BackwardProc() \n \ + :Ctrlm: MoveNowProc() \n \ + :Ctrlx: RetractMoveProc() \n \ + :MetaJ: EngineMenuProc() \n \ + :MetaU: UciMenuProc() \n \ + :MetaT: TimeControlProc() \n \ + :CtrlQ: AlwaysQueenProc() \n \ + :CtrlF: AutoflagProc() \n \ + :CtrlA: AnimateMovingProc() \n \ + :CtrlP: PonderNextMoveProc() \n \ + :CtrlL: TestLegalityProc() \n \ + :CtrlH: HideThinkingProc() \n \ + :-: Iconify() \n \ + :F1: ManProc() \n \ + :F2: FlipViewProc() \n \ + .: BackwardProc() \n \ + .: ForwardProc() \n \ Shift1: AskQuestionProc(\"Direct command\",\ \"Send to chess program:\",,1) \n \ Shift2: AskQuestionProc(\"Direct command\",\ @@ -1027,6 +1101,10 @@ char ICSInputTranslations[] = "Down: DownKeyProc() \n " "Return: EnterKeyProc() \n"; +// [HGM] vari: another hideous kludge: call extend-end first so we can be sure select-start works, +// as the widget is destroyed before the up-click can call extend-end +char commentTranslations[] = ": extend-end() select-start() CommentClick() \n"; + String xboardResources[] = { "*fileName*value.translations: #override\\n Return: FileNameAction()", "*question*value.translations: #override\\n Return: AskQuestionReplyAction()", @@ -1294,10 +1372,10 @@ extern char *crWhite, * crBlack; void * colorVariable[] = { - &appData.whitePieceColor, - &appData.blackPieceColor, + &appData.whitePieceColor, + &appData.blackPieceColor, &appData.lightSquareColor, - &appData.darkSquareColor, + &appData.darkSquareColor, &appData.highlightSquareColor, &appData.premoveHighlightColor, &appData.lowTimeWarningColor, @@ -1367,7 +1445,7 @@ ParseColor(int n, char *name) void ParseTextAttribs(ColorClass cc, char *s) -{ +{ (&appData.colorShout)[cc] = strdup(s); } @@ -1391,7 +1469,7 @@ SetCommPortDefaults() void SaveFontArg(FILE *f, ArgDescriptor *ad) { - char *name, buf[MSG_SIZ]; + char *name; int i, n = (int)ad->argLoc; switch(n) { case 0: // CLOCK_FONT @@ -1413,7 +1491,7 @@ SaveFontArg(FILE *f, ArgDescriptor *ad) break; } for(i=0; iargName, i, fontTable[n][i]); + fprintf(f, OPTCHAR "%s" SEPCHAR "size%d:%s\n", ad->argName, i, fontTable[n][i]); } void @@ -1456,7 +1534,7 @@ GetActualPlacement(Widget wg, WindowPlacement *wp) int i; if(!wg) return; - + i = 0; XtSetArg(args[i], XtNx, &x); i++; XtSetArg(args[i], XtNy, &y); i++; @@ -1493,7 +1571,9 @@ int MySearchPath(char *installDir, char *name, char *fullname) { // just append installDir and name. Perhaps ExpandPath should be used here? name = ExpandPathName(name); - if(name && name[0] == '/') strcpy(fullname, name); else { + if(name && name[0] == '/') + safeStrCpy(fullname, name, MSG_SIZ ); + else { sprintf(fullname, "%s%c%s", installDir, '/', name); } return 1; @@ -1503,7 +1583,7 @@ int MyGetFullPathName(char *name, char *fullname) { // should use ExpandPath? name = ExpandPathName(name); - strcpy(fullname, name); + safeStrCpy(fullname, name, MSG_SIZ ); return 1; } @@ -1523,6 +1603,7 @@ void PopUpStartupDialog() { // start menu not implemented in XBoard } + char * ConvertToLine(int argc, char **argv) { @@ -1530,19 +1611,24 @@ ConvertToLine(int argc, char **argv) int i; line[0] = NULLCHAR; - for(i=1; i ", ReadlineCompleteHandler); + rl_readline_name="XBoard"; +# endif if(argc > 1 && (!strcmp(argv[1], "-v" ) || !strcmp(argv[1], "--version" ))) { printf("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); @@ -1997,7 +2082,7 @@ XBoard square size (hint): %d\n\ if (forceMono) { fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"), programName); - + if (appData.bitmapDirectory == NULL || appData.bitmapDirectory[0] == NULLCHAR) appData.bitmapDirectory = DEF_BITMAP_DIR; @@ -2007,7 +2092,7 @@ XBoard square size (hint): %d\n\ vFrom.addr = (caddr_t) appData.lowTimeWarningColor; vFrom.size = strlen(appData.lowTimeWarningColor); XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) + if (vTo.addr == NULL) appData.monoMode = True; else lowTimeWarningColor = *(Pixel *) vTo.addr; @@ -2489,11 +2574,11 @@ XBoard square size (hint): %d\n\ HistoryPopUp(); } - if( wpEvalGraph.visible ) + if( wpEvalGraph.visible ) { EvalGraphPopUp(); }; - + if( wpEngineOutput.visible ) { EngineOutputPopUp(); } @@ -2519,6 +2604,7 @@ XBoard square size (hint): %d\n\ } gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes() InitPosition(TRUE); + XtSetKeyboardFocus(shellWidget, formWidget); XtAppMainLoop(appContext); if (appData.debugMode) fclose(debugFP); // [DM] debug @@ -2534,6 +2620,13 @@ ShutDownFrontEnd() if (saveSettingsOnExit) SaveSettings(settingsFileName); unlink(gameCopyFilename); unlink(gamePasteFilename); + +# if HAVE_LIBREADLINE + /* remove gnu-readline handler. */ + rl_callback_handler_remove(); +#endif + + return; } RETSIGTYPE TermSizeSigHandler(int sig) @@ -2580,22 +2673,33 @@ CmailSigHandlerCallBack(isr, closure, message, count, error) void ICSInitScript() { - FILE *f; - char buf[MSG_SIZ]; - char *p; + /* try to open the icsLogon script, either in the location given + * or in the users HOME directory + */ + + FILE *f; + char buf[MSG_SIZ]; + char *homedir; - f = fopen(appData.icsLogon, "r"); - if (f == NULL) { - p = getenv("HOME"); - if (p != NULL) { - strcpy(buf, p); - strcat(buf, "/"); - strcat(buf, appData.icsLogon); - f = fopen(buf, "r"); + f = fopen(appData.icsLogon, "r"); + if (f == NULL) + { + homedir = getenv("HOME"); + if (homedir != NULL) + { + safeStrCpy(buf, homedir, sizeof(buf)/sizeof(buf[0]) ); + strncat(buf, "/", MSG_SIZ - strlen(buf) - 1); + strncat(buf, appData.icsLogon, MSG_SIZ - strlen(buf) - 1); + f = fopen(buf, "r"); } } - if (f != NULL) - ProcessICSInitScript(f); + + if (f != NULL) + ProcessICSInitScript(f); + else + printf("Warning: Couldn't open icsLogon file (checked %s and %s).\n", appData.icsLogon, buf); + + return; } void @@ -2624,6 +2728,12 @@ GreyRevert(grey) } else { XtSetSensitive(w, !grey); } + w = XtNameToWidget(menuBarWidget, "menuStep.Annotate"); + if (w == NULL) { + DisplayError("menuStep.Annotate", 0); + } else { + XtSetSensitive(w, !grey); + } } void @@ -2659,6 +2769,7 @@ Enables icsEnables[] = { { "menuOptions.Hide Thinking", False }, { "menuOptions.Ponder Next Move", False }, #endif + { "menuStep.Annotate", False }, { NULL, False } }; @@ -2674,6 +2785,7 @@ Enables ncpEnables[] = { { "menuMode.ICS Input Box", False }, { "Action", False }, { "menuStep.Revert", False }, + { "menuStep.Annotate", False }, { "menuStep.Move Now", False }, { "menuStep.Retract Move", False }, { "menuOptions.Auto Comment", False }, @@ -2704,6 +2816,7 @@ Enables gnuEnables[] = { { "menuAction.Stop Observing", False }, { "menuAction.Upload to Examine", False }, { "menuStep.Revert", False }, + { "menuStep.Annotate", False }, { "menuOptions.Auto Comment", False }, { "menuOptions.Auto Observe", False }, { "menuOptions.Auto Raise Board", False }, @@ -2797,7 +2910,7 @@ void SetICSMode() { SetMenuEnables(icsEnables); -#ifdef ZIPPY +#if ZIPPY if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */ XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True); #endif @@ -2920,7 +3033,8 @@ NextInHistory() * The return value should be freed with XtFree when no * longer needed. */ -char *FindFont(pattern, targetPxlSize) +char * +FindFont(pattern, targetPxlSize) char *pattern; int targetPxlSize; { @@ -2935,7 +3049,7 @@ char *FindFont(pattern, targetPxlSize) XFontStruct **fnt_list; base_fnt_lst = calloc(1, strlen(pattern) + 3); - sprintf(strInt, "%d", targetPxlSize); + snprintf(strInt, sizeof(strInt)/sizeof(strInt[0]), "%d", targetPxlSize); p = strstr(pattern, "--"); strncpy(base_fnt_lst, pattern, p - pattern + 2); strcat(base_fnt_lst, strInt); @@ -2994,8 +3108,8 @@ char *FindFont(pattern, targetPxlSize) while (isdigit(*scalableTail)) scalableTail++; sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail); } else { - p = (char *) XtMalloc(strlen(best) + 1); - strcpy(p, best); + p = (char *) XtMalloc(strlen(best) + 2); + safeStrCpy(p, best, strlen(best)+1 ); } if (appData.debugMode) { fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"), @@ -3381,7 +3495,7 @@ void CreateXPMPieces() exit(1); } } - if(piece <= (int) WhiteKing) + if(piece <= (int) WhiteKing) xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece]; } } @@ -3435,12 +3549,12 @@ void CreatePieces() for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) { for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) { - sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", - pieceBitmapNames[piece], - ss, kind == SOLID ? 's' : 'o'); - ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss); - if(piece <= (int)WhiteKing) - pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; + snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", + pieceBitmapNames[piece], + ss, kind == SOLID ? 's' : 'o'); + ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss); + if(piece <= (int)WhiteKing) + pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; } } @@ -3463,13 +3577,13 @@ void CreatePieces() for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) { for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) { - sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", - pieceBitmapNames[piece], - ss, kind == SOLID ? 's' : 'o'); - ReadBitmap(&pieceBitmap2[kind][piece], buf, - bib->bits[kind][piece], ss, ss); - if(piece <= (int)WhiteKing) - pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; + snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "", + pieceBitmapNames[piece], + ss, kind == SOLID ? 's' : 'o'); + ReadBitmap(&pieceBitmap2[kind][piece], buf, + bib->bits[kind][piece], ss, ss); + if(piece <= (int)WhiteKing) + pieceBitmap[kind][piece] = pieceBitmap2[kind][piece]; } } @@ -3490,12 +3604,12 @@ void ReadBitmap(pm, name, bits, wreq, hreq) char msg[MSG_SIZ], fullname[MSG_SIZ]; if (*appData.bitmapDirectory != NULLCHAR) { - strcpy(fullname, appData.bitmapDirectory); - strcat(fullname, "/"); - strcat(fullname, name); - errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname, - &w, &h, pm, &x_hot, &y_hot); - fprintf(stderr, "load %s\n", name); + safeStrCpy(fullname, appData.bitmapDirectory, sizeof(fullname)/sizeof(fullname[0]) ); + strncat(fullname, "/", MSG_SIZ - strlen(fullname) - 1); + strncat(fullname, name, MSG_SIZ - strlen(fullname) - 1); + errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname, + &w, &h, pm, &x_hot, &y_hot); + fprintf(stderr, "load %s\n", name); if (errcode != BitmapSuccess) { switch (errcode) { case BitmapOpenFailed: @@ -3612,8 +3726,8 @@ Widget CreateMenuBar(mb) formWidget, args, j); while (mb->name != NULL) { - strcpy(menuName, "menu"); - strcat(menuName, mb->name); + safeStrCpy(menuName, "menu", sizeof(menuName)/sizeof(menuName[0]) ); + strncat(menuName, mb->name, MSG_SIZ - strlen(menuName) - 1); j = 0; XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++; if (tinyLayout) { @@ -3773,7 +3887,7 @@ void PieceMenuPopup(w, event, params, num_params) { String whichMenu; int menuNr; if (event->type == ButtonRelease) - menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); + menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); else if (event->type == ButtonPress) menuNr = RightClick(Press, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); switch(menuNr) { @@ -4174,6 +4288,8 @@ void DrawSquare(row, column, piece, do_flash) (squareSize + lineGap); } + if(twoBoards && partnerUp) x += hOffset; // [HGM] dual: draw second board + square_color = SquareColor(row, column); if ( // [HGM] holdings: blank out area between board and holdings @@ -4259,8 +4375,8 @@ void DrawSquare(row, column, piece, do_flash) x + 2, y + font_ascent + 1, string, 1); } } - if(marker[row][column]) { - XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, + if(!partnerUp && marker[row][column]) { + XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); } } @@ -4279,6 +4395,11 @@ void EventProc(widget, unused, event) case Expose: if (event->xexpose.count > 0) return; /* no clipping is done */ XDrawPosition(widget, True, NULL); + if(twoBoards) { // [HGM] dual: draw other board in other orientation + flipView = !flipView; partnerUp = !partnerUp; + XDrawPosition(widget, True, NULL); + flipView = !flipView; partnerUp = !partnerUp; + } break; case MotionNotify: if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break; @@ -4362,7 +4483,7 @@ static int check_castle_draw(newb, oldb, rrow, rcol) return 0; } -// [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph +// [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph void DrawSeekAxis( int x, int y, int xTo, int yTo ) { XDrawLine(xDisplay, xBoardWindow, lineGC, x, y, xTo, yTo); @@ -4388,11 +4509,11 @@ void DrawSeekDot(int x, int y, int colorNr) XFillRectangle(xDisplay, xBoardWindow, color, x-squareSize/9, y-squareSize/9, 2*squareSize/9, 2*squareSize/9); else - XFillArc(xDisplay, xBoardWindow, color, + XFillArc(xDisplay, xBoardWindow, color, x-squareSize/8, y-squareSize/8, squareSize/4, squareSize/4, 0, 64*360); } -static int damage[BOARD_RANKS][BOARD_FILES]; +static int damage[2][BOARD_RANKS][BOARD_FILES]; /* * event handler for redrawing the board @@ -4404,18 +4525,19 @@ void XDrawPosition(w, repaint, board) { int i, j, do_flash; static int lastFlipView = 0; - static int lastBoardValid = 0; - static Board lastBoard; + static int lastBoardValid[2] = {0, 0}; + static Board lastBoard[2]; Arg args[16]; int rrow, rcol; + int nr = twoBoards*partnerUp; if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up if (board == NULL) { - if (!lastBoardValid) return; - board = lastBoard; + if (!lastBoardValid[nr]) return; + board = lastBoard[nr]; } - if (!lastBoardValid || lastFlipView != flipView) { + if (!lastBoardValid[nr] || (nr == 0 && lastFlipView != flipView)) { XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None)); XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"), args, 1); @@ -4426,19 +4548,19 @@ void XDrawPosition(w, repaint, board) * but this causes a very distracting flicker. */ - if (!repaint && lastBoardValid && lastFlipView == flipView) { + if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) { /* If too much changes (begin observing new game, etc.), don't do flashing */ - do_flash = too_many_diffs(board, lastBoard) ? 0 : 1; + do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1; /* Special check for castling so we don't flash both the king and the rook (just flash the king). */ if (do_flash) { - if (check_castle_draw(board, lastBoard, &rrow, &rcol)) { + if (check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) { /* Draw rook with NO flashing. King will be drawn flashing later */ DrawSquare(rrow, rcol, board[rrow][rcol], 0); - lastBoard[rrow][rcol] = board[rrow][rcol]; + lastBoard[nr][rrow][rcol] = board[rrow][rcol]; } } @@ -4447,32 +4569,34 @@ void XDrawPosition(w, repaint, board) is flashing on its new square */ for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) - if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare) - || damage[i][j]) { + if ((board[i][j] != lastBoard[nr][i][j] && board[i][j] == EmptySquare) + || damage[nr][i][j]) { DrawSquare(i, j, board[i][j], 0); - damage[i][j] = False; + damage[nr][i][j] = False; } /* Second pass -- Draw piece(s) in new position and flash them */ for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) - if (board[i][j] != lastBoard[i][j]) { + if (board[i][j] != lastBoard[nr][i][j]) { DrawSquare(i, j, board[i][j], do_flash); } } else { if (lineGap > 0) XDrawSegments(xDisplay, xBoardWindow, lineGC, + twoBoards & partnerUp ? secondSegments : // [HGM] dual gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2); for (i = 0; i < BOARD_HEIGHT; i++) for (j = 0; j < BOARD_WIDTH; j++) { DrawSquare(i, j, board[i][j], 0); - damage[i][j] = False; + damage[nr][i][j] = False; } } - CopyBoard(lastBoard, board); - lastBoardValid = 1; + CopyBoard(lastBoard[nr], board); + lastBoardValid[nr] = 1; + if(nr == 0) { // [HGM] dual: no highlights on second board yet lastFlipView = flipView; /* Draw highlights */ @@ -4488,7 +4612,7 @@ void XDrawPosition(w, repaint, board) if (hi2X >= 0 && hi2Y >= 0) { drawHighlight(hi2X, hi2Y, highlineGC); } - + } /* If piece being dragged around board, must redraw that too */ DrawDragPiece(); @@ -4607,6 +4731,7 @@ Widget CommentCreate(name, text, mutable, callback, lines) XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; edit = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j); + XtOverrideTranslations(edit, XtParseTranslationTable(commentTranslations)); if (mutable) { j = 0; @@ -4815,6 +4940,20 @@ Widget MiscCreate(name, text, mutable, callback, lines) static int savedIndex; /* gross that this is global */ +void CommentClick (Widget w, XEvent * event, String * params, Cardinal * nParams) +{ + String val; + XawTextPosition index, dummy; + Arg arg; + + XawTextGetSelectionPos(w, &index, &dummy); + XtSetArg(arg, XtNstring, &val); + XtGetValues(w, &arg, 1); + ReplaceComment(savedIndex, val); + if(savedIndex != currentMove) ToNrEvent(savedIndex); + LoadVariation( index, val ); // [HGM] also does the actual moving to it, now +} + void EditCommentPopUp(index, title, text) int index; char *title, *text; @@ -4976,6 +5115,7 @@ void CommentPopUp(title, text) int j; Widget edit; + savedIndex = currentMove; // [HGM] vari if (commentShell == NULL) { commentShell = CommentCreate(title, text, False, CommentCallback, 4); @@ -5042,13 +5182,6 @@ void FileNamePopUp(label, def, proc, openMode) FileProc proc; char *openMode; { - Arg args[16]; - Widget popup, layout, dialog, edit; - Window root, child; - int x, y, i; - int win_x, win_y; - unsigned int mask; - fileProc = proc; /* I can't see a way not */ fileOpenMode = openMode; /* to use globals here */ { // [HGM] use file-selector dialog stolen from Ghostview @@ -5056,8 +5189,8 @@ void FileNamePopUp(label, def, proc, openMode) int index; // this is not supported yet FILE *f; if(f = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ", - NULL, openMode, NULL, &name)) - (void) (*fileProc)(f, index=0, name); + def, openMode, NULL, &name)) + (void) (*fileProc)(f, index=0, name); } } @@ -5103,7 +5236,7 @@ void FileNameAction(w, event, prms, nprms) name = XawDialogGetValueString(w = XtParent(w)); if ((name != NULL) && (*name != NULLCHAR)) { - strcpy(buf, name); + safeStrCpy(buf, name, sizeof(buf)/sizeof(buf[0]) ); XtPopdown(w = XtParent(XtParent(w))); XtDestroyWidget(w); filenameUp = False; @@ -5179,8 +5312,8 @@ void PromotionPopUp() XawDialogAddButton(dialog, _("King"), PromotionCallback, (XtPointer) dialog); } - if(gameInfo.variant == VariantCapablanca || - gameInfo.variant == VariantGothic || + if(gameInfo.variant == VariantCapablanca || + gameInfo.variant == VariantGothic || gameInfo.variant == VariantCapaRandom) { XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback, (XtPointer) dialog); @@ -5633,7 +5766,7 @@ SendPositionSelection(Widget w, Atom *selection, Atom *target, * automatically call XtFree on the value returned. So have to * make a copy of it allocated with XtMalloc */ selection_tmp= XtMalloc(strlen(selected_fen_position)+16); - strcpy(selection_tmp, selected_fen_position); + safeStrCpy(selection_tmp, selected_fen_position, sizeof(selection_tmp)/sizeof(selection_tmp[0]) ); *value_return=selection_tmp; *length_return=strlen(selection_tmp); @@ -5708,7 +5841,7 @@ void PastePositionProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - XtGetSelectionValue(menuBarWidget, + XtGetSelectionValue(menuBarWidget, appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING, /* (XtSelectionCallbackProc) */ PastePositionCB, NULL, /* client_data passed to PastePositionCB */ @@ -5898,7 +6031,7 @@ void AnalyzeModeProc(w, event, prms, nprms) /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */ if (appData.icsActive) { if (gameMode != IcsObserving) { - sprintf(buf,_("You are not observing a game")); + snprintf(buf, MSG_SIZ, _("You are not observing a game")); DisplayError(buf, 0); /* secure check */ if (appData.icsEngineAnalyze) { @@ -6247,7 +6380,16 @@ void RevertProc(w, event, prms, nprms) String *prms; Cardinal *nprms; { - RevertEvent(); + RevertEvent(False); +} + +void AnnotateProc(w, event, prms, nprms) + Widget w; + XEvent *event; + String *prms; + Cardinal *nprms; +{ + RevertEvent(True); } void TruncateGameProc(w, event, prms, nprms) @@ -6948,23 +7090,23 @@ void DisplayMessage(message, extMessage) char *message, *extMessage; { /* display a message in the message widget */ - + char buf[MSG_SIZ]; Arg arg; - - if (extMessage) + + if (extMessage) { - if (*message) + if (*message) { snprintf(buf, sizeof(buf), "%s %s", message, extMessage); message = buf; - } - else + } + else { message = extMessage; }; }; - + /* need to test if messageWidget already exists, since this function can also be called during the startup, if for example a Xresource is not set up correctly */ @@ -6973,7 +7115,7 @@ void DisplayMessage(message, extMessage) XtSetArg(arg, XtNlabel, message); XtSetValues(messageWidget, &arg, 1); }; - + return; } @@ -6994,8 +7136,8 @@ void DisplayTitle(text) } if (*text != NULLCHAR) { - strcpy(icon, text); - strcpy(title, text); + safeStrCpy(icon, text, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, text, sizeof(title)/sizeof(title[0]) ); } else if (appData.icsActive) { snprintf(icon, sizeof(icon), "%s", appData.icsHost); snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost); @@ -7005,19 +7147,19 @@ void DisplayTitle(text) #ifdef GOTHIC // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it } else if (gameInfo.variant == VariantGothic) { - strcpy(icon, programName); - strcpy(title, GOTHIC); + safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, GOTHIC, sizeof(title)/sizeof(title[0]) ); #endif #ifdef FALCON } else if (gameInfo.variant == VariantFalcon) { - strcpy(icon, programName); - strcpy(title, FALCON); + safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, FALCON, sizeof(title)/sizeof(title[0]) ); #endif } else if (appData.noChessProgram) { - strcpy(icon, programName); - strcpy(title, programName); + safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) ); + safeStrCpy(title, programName, sizeof(title)/sizeof(title[0]) ); } else { - strcpy(icon, first.tidy); + safeStrCpy(icon, first.tidy, sizeof(icon)/sizeof(icon[0]) ); snprintf(title,sizeof(title), "%s: %s", programName, first.tidy); } i = 0; @@ -7027,7 +7169,8 @@ void DisplayTitle(text) } -void DisplayError(message, error) +void +DisplayError(message, error) String message; int error; { @@ -7175,10 +7318,10 @@ void AskQuestionReplyAction(w, event, prms, nprms) String reply; reply = XawDialogGetValueString(w = XtParent(w)); - strcpy(buf, pendingReplyPrefix); - if (*buf) strcat(buf, " "); - strcat(buf, reply); - strcat(buf, "\n"); + safeStrCpy(buf, pendingReplyPrefix, sizeof(buf)/sizeof(buf[0]) ); + if (*buf) strncat(buf, " ", MSG_SIZ - strlen(buf) - 1); + strncat(buf, reply, MSG_SIZ - strlen(buf) - 1); + strncat(buf, "\n", MSG_SIZ - strlen(buf) - 1); OutputToProcess(pendingReplyPR, buf, strlen(buf), &err); AskQuestionPopDown(); @@ -7213,7 +7356,7 @@ void AskQuestion(title, question, replyPrefix, pr) int win_x, win_y; unsigned int mask; - strcpy(pendingReplyPrefix, replyPrefix); + safeStrCpy(pendingReplyPrefix, replyPrefix, sizeof(pendingReplyPrefix)/sizeof(pendingReplyPrefix[0]) ); pendingReplyPR = pr; i = 0; @@ -7330,18 +7473,18 @@ Colorize(cc, continuation) if (textColors[(int)cc].bg > 0) { if (textColors[(int)cc].fg > 0) { - sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr, - textColors[(int)cc].fg, textColors[(int)cc].bg); + snprintf(buf, MSG_SIZ, "\033[0;%d;%d;%dm", textColors[(int)cc].attr, + textColors[(int)cc].fg, textColors[(int)cc].bg); } else { - sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr, - textColors[(int)cc].bg); + snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr, + textColors[(int)cc].bg); } } else { if (textColors[(int)cc].fg > 0) { - sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr, + snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr, textColors[(int)cc].fg); } else { - sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr); + snprintf(buf, MSG_SIZ, "\033[0;%dm", textColors[(int)cc].attr); } } count = strlen(buf); @@ -7391,11 +7534,12 @@ char *UserName() return getpwuid(getuid())->pw_name; } -static char *ExpandPathName(path) +static char * +ExpandPathName(path) char *path; { - static char static_buf[2000]; - char *d, *s, buf[2000]; + static char static_buf[4*MSG_SIZ]; + char *d, *s, buf[4*MSG_SIZ]; struct passwd *pwd; s = path; @@ -7411,25 +7555,25 @@ static char *ExpandPathName(path) if (*s == '~') { if (*(s+1) == '/') { - strcpy(d, getpwuid(getuid())->pw_dir); - strcat(d, s+1); + safeStrCpy(d, getpwuid(getuid())->pw_dir, 4*MSG_SIZ ); + strcat(d, s+1); } else { - strcpy(buf, s+1); - *strchr(buf, '/') = 0; - pwd = getpwnam(buf); - if (!pwd) - { - fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"), - buf, path); - return NULL; - } - strcpy(d, pwd->pw_dir); - strcat(d, strchr(s+1, '/')); + safeStrCpy(buf, s+1, sizeof(buf)/sizeof(buf[0]) ); + *strchr(buf, '/') = 0; + pwd = getpwnam(buf); + if (!pwd) + { + fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"), + buf, path); + return NULL; + } + safeStrCpy(d, pwd->pw_dir, 4*MSG_SIZ ); + strcat(d, strchr(s+1, '/')); } } else - strcpy(d, s); + safeStrCpy(d, s, 4*MSG_SIZ ); return static_buf; } @@ -7604,16 +7748,16 @@ DisplayTimerLabel(w, color, timer, highlight) Pixel foregroundOrWarningColor = timerForegroundPixel; if (timer > 0 && - appData.lowTimeWarning && + appData.lowTimeWarning && (timer / 1000) < appData.icsAlarmTime) foregroundOrWarningColor = lowTimeWarningColor; if (appData.clockMode) { - sprintf(buf, "%s: %s", color, TimeString(timer)); - XtSetArg(args[0], XtNlabel, buf); + snprintf(buf, MSG_SIZ, "%s: %s", color, TimeString(timer)); + XtSetArg(args[0], XtNlabel, buf); } else { - sprintf(buf, "%s ", color); - XtSetArg(args[0], XtNlabel, buf); + snprintf(buf, MSG_SIZ, "%s ", color); + XtSetArg(args[0], XtNlabel, buf); } if (highlight) { @@ -7694,7 +7838,7 @@ int StartChildProcess(cmdLine, dir, pr) most simple-minded way possible. */ i = 0; - strcpy(buf, cmdLine); + safeStrCpy(buf, cmdLine, sizeof(buf)/sizeof(buf[0]) ); p = buf; for (;;) { while(*p == ' ') p++; @@ -7962,16 +8106,97 @@ DoInputCallback(closure, source, xid) } q = is->buf; while (p < is->unused) { - *q++ = *p++; + *q++ = *p++; } is->unused = q; } else { - count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE); - if (count == -1) - error = errno; - else - error = 0; - (is->func)(is, is->closure, is->buf, count, error); +# if HAVE_LIBREADLINE + /* check if input is from stdin, if yes, use gnu-readline */ + if( is->fd==fileno(stdin) ) + { + /* to clear the line */ + printf("\r \r"); + + /* read from stdin */ + rl_callback_read_char(); + /* redisplay the current line */ + if(sending_ICS_password) + { + int i; char buf[MSG_SIZ]; + + bzero(buf,MSG_SIZ); + + /* blank the password */ + count = strlen(rl_line_buffer); + if(count>MSG_SIZ-1) + { + printf("PROBLEM with readline\n"); + count=MSG_SIZ; + } + for(i=0;iINPUT_SOURCE_BUF_SIZE-1) + { + printf("PROBLEM with readline\n"); + count = INPUT_SOURCE_BUF_SIZE; + }; + strncpy(is->buf,readline_buffer,count); + is->buf[count]='\n';count++; + + /* reset gnu-readline state */ + free(readline_buffer); + readline_buffer=NULL; + readline_complete=0; + + if (count == -1) + error = errno; + else + error = 0; + (is->func)(is, is->closure, is->buf, count, error); + + /* are we done with the password? */ + if(sending_ICS_password) + sending_ICS_password=0; + if(sending_ICS_login) + sending_ICS_login=0; + } + } + else + { + /* input not from stdin, use default method */ + count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE); + if (count == -1) + error = errno; + else + error = 0; + (is->func)(is, is->closure, is->buf, count, error); + }; +#else /* no readline support */ + count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE); + if (count == -1) + error = errno; + else + error = 0; + (is->func)(is, is->closure, is->buf, count, error); +#endif + } } @@ -8027,28 +8252,36 @@ int OutputToProcess(pr, message, count, outError) ChildProc *cp = (ChildProc *) pr; int outCount; + if (pr == NoProc) { - if (appData.noJoin || !appData.useInternalWrap) - outCount = fwrite(message, 1, count, stdout); - else + if (appData.noJoin || !appData.useInternalWrap) + outCount = fwrite(message, 1, count, stdout); + else { - int width = get_term_width(); - int len = wrap(NULL, message, count, width, &line); - char *msg = malloc(len); - int dbgchk; - - if (!msg) - outCount = fwrite(message, 1, count, stdout); - else + int width = get_term_width(); + int len = wrap(NULL, message, count, width, &line); + char *msg = malloc(len); + int dbgchk; + + if (!msg) + outCount = fwrite(message, 1, count, stdout); + else { - dbgchk = wrap(msg, message, count, width, &line); - if (dbgchk != len && appData.debugMode) - fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len); - outCount = fwrite(msg, 1, dbgchk, stdout); - free(msg); + dbgchk = wrap(msg, message, count, width, &line); + if (dbgchk != len && appData.debugMode) + fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len); + outCount = fwrite(msg, 1, dbgchk, stdout); + free(msg); } } + +# if HAVE_LIBREADLINE + /* readline support */ + if(strlen(rl_line_buffer)) + printf("\n> %s",rl_line_buffer); +#endif + } else outCount = write(cp->fdTo, message, count); @@ -8652,8 +8885,8 @@ AnimateMove(board, fromX, fromY, toX, toY) if (!appData.animate || appData.blindfold) return; - if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing || - board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing) + if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing || + board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing) return; // [HGM] FRC: no animtion of FRC castlings, as to-square is not true to-square if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return; @@ -8696,7 +8929,7 @@ AnimateMove(board, fromX, fromY, toX, toY) FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames); /* Be sure end square is redrawn */ - damage[toY][toX] = True; + damage[0][toY][toX] = True; } void @@ -8736,7 +8969,7 @@ DragPieceBegin(x, y) XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC, corner.x, corner.y, squareSize, squareSize, 0, 0); // [HGM] zh: unstack in stead of grab - damage[boardY][boardX] = True; + damage[0][boardY][boardX] = True; } else { player.dragActive = False; } @@ -8790,7 +9023,7 @@ DragPieceEnd(x, y) EndAnimation(&player, &corner); /* Be sure end square is redrawn */ - damage[boardY][boardX] = True; + damage[0][boardY][boardX] = True; /* This prevents weird things happening with fast successive clicks which on my Sun at least can cause motion events @@ -8813,7 +9046,7 @@ DrawDragPiece () BlankSquare(player.startSquare.x, player.startSquare.y, player.startColor, EmptySquare, xBoardWindow); AnimationFrame(&player, &player.prevFrame, player.dragPiece); - damage[player.startBoardY][player.startBoardX] = TRUE; + damage[0][player.startBoardY][player.startBoardX] = TRUE; } #include @@ -8836,17 +9069,33 @@ int get_term_width() return default_width; } -void update_ics_width() +void +update_ics_width() { - static int old_width = 0; - int new_width = get_term_width(); + static int old_width = 0; + int new_width = get_term_width(); - if (old_width != new_width) - ics_printf("set width %d\n", new_width); - old_width = new_width; + if (old_width != new_width) + ics_printf("set width %d\n", new_width); + old_width = new_width; } void NotifyFrontendLogin() { update_ics_width(); } + +# if HAVE_LIBREADLINE +static void +ReadlineCompleteHandler(char* ptr) +{ + /* make gnu-readline keep the history */ + readline_buffer = ptr; + readline_complete = 1; + + if (ptr && *ptr && !sending_ICS_password && !sending_ICS_login) + add_history(ptr); + + return; +} +#endif