X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=909ca8573277e0c0a245e14f4dbd796db35f95fd;hb=ca99bd4de57d0b079024cbdf5435de1ae61d5fd9;hp=79b61a29602e4d2f99b69e99dc47040ad61f95c1;hpb=a5b8066ad78ddeec1ddcca3b31ee26fe1052fc89;p=xboard.git diff --git a/xboard.c b/xboard.c index 79b61a2..909ca85 100644 --- a/xboard.c +++ b/xboard.c @@ -232,6 +232,7 @@ typedef struct { int main P((int argc, char **argv)); RETSIGTYPE CmailSigHandler P((int sig)); RETSIGTYPE IntSigHandler P((int sig)); +RETSIGTYPE TermSizeSigHandler P((int sig)); void CreateGCs P((void)); void CreateXIMPieces P((void)); void CreateXPMPieces P((void)); @@ -280,7 +281,6 @@ void AskQuestionReplyAction P((Widget w, XEvent *event, void AskQuestionProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AskQuestionPopDown P((void)); -void PromotionPopUp P((void)); void PromotionPopDown P((void)); void PromotionCallback P((Widget w, XtPointer client_data, XtPointer call_data)); @@ -427,9 +427,7 @@ void ErrorPopUp P((char *title, char *text, int modal)); void ErrorPopDown P((void)); static char *ExpandPathName P((char *path)); static void CreateAnimVars P((void)); -static void DragPieceBegin P((int x, int y)); static void DragPieceMove P((int x, int y)); -static void DragPieceEnd P((int x, int y)); static void DrawDragPiece P((void)); char *ModeToWidgetName P((GameMode mode)); void EngineOutputUpdate( FrontEndProgramStats * stats ); @@ -446,6 +444,8 @@ void UciPopDown P(()); void TimeControlPopDown P(()); void NewVariantPopDown P(()); void SettingsPopDown P(()); +void update_ics_width P(()); +int get_term_width P(()); /* * XBoard depends on Xt R4 or higher */ @@ -1407,6 +1407,15 @@ XtResource clientResources[] = { { "forceIllegalMoves", "forceIllegalMoves", XtRBoolean, sizeof(Boolean), XtOffset(AppDataPtr, forceIllegal), XtRImmediate, (XtPointer) False}, + { "keepLineBreaksICS", "keepLineBreaksICS", XtRBoolean, + sizeof(Boolean), XtOffset(AppDataPtr, noJoin), + XtRImmediate, (XtPointer) False}, + { "wrapContinuationSequence", "wrapContinuationSequence", XtRString, + sizeof(String), XtOffset(AppDataPtr, wrapContSeq), + XtRString, ""}, + { "useInternalWrap", "useInternalWrap", XtRBoolean, + sizeof(Boolean), XtOffset(AppDataPtr, useInternalWrap), + XtRImmediate, (XtPointer) True}, }; XrmOptionDescRec shellOptions[] = { @@ -1776,9 +1785,11 @@ XrmOptionDescRec shellOptions[] = { { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL }, { "-keepAlive", "keepAlive", XrmoptionSepArg, NULL }, { "-forceIllegalMoves", "forceIllegalMoves", XrmoptionNoArg, "True" }, + { "-keepLineBreaksICS", "keepLineBreaksICS", XrmoptionSepArg, NULL }, + { "-wrapContinuationSequence", "wrapContinuationSequence", XrmoptionSepArg, NULL }, + { "-useInternalWrap", "useInternalWrap", XrmoptionSepArg, NULL }, }; - XtActionsRec boardActions[] = { { "DrawPosition", DrawPositionProc }, { "HandleUserMove", HandleUserMove }, @@ -1890,7 +1901,6 @@ XtActionsRec boardActions[] = { { "TagsPopDown", (XtActionProc) TagsPopDown }, { "ErrorPopDown", (XtActionProc) ErrorPopDown }, { "ICSInputBoxPopDown", (XtActionProc) ICSInputBoxPopDown }, - { "AnalysisPopDown", (XtActionProc) AnalysisPopDown }, { "FileNamePopDown", (XtActionProc) FileNamePopDown }, { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown }, { "GameListPopDown", (XtActionProc) GameListPopDown }, @@ -2392,11 +2402,6 @@ main(argc, argv) argvCopy[j] = NULL; argv = argvCopy; argc = j; -#if 0 - if(appData.debugMode,1) { // OK, appData is not initialized here yet... - for(i=0; i 0 ? appData.NrFiles : 8; - gameInfo.boardHeight = appData.NrRanks > 0 ? appData.NrRanks : 8; - gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0; -#endif - #ifdef IDSIZE InitDrawingSizes(-1, 0); // [HGM] initsize: make this into a subroutine @@ -2785,6 +2777,7 @@ XBoard square size (hint): %d\n\ widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar); XtSetArg(args[0], XtNtop, XtChainTop); XtSetArg(args[1], XtNbottom, XtChainTop); + XtSetArg(args[1], XtNright, XtChainLeft); XtSetValues(menuBarWidget, args, 2); widgetList[j++] = whiteTimerWidget = @@ -3201,6 +3194,9 @@ XBoard square size (hint): %d\n\ if (appData.icsInputBox) ICSInputBoxPopUp(); } + #ifdef SIGWINCH + signal(SIGWINCH, TermSizeSigHandler); + #endif signal(SIGINT, IntSigHandler); signal(SIGTERM, IntSigHandler); if (*appData.cmailGameName != NULLCHAR) { @@ -3225,6 +3221,11 @@ ShutDownFrontEnd() unlink(gamePasteFilename); } +RETSIGTYPE TermSizeSigHandler(int sig) +{ + update_ics_width(); +} + RETSIGTYPE IntSigHandler(sig) int sig; @@ -3918,14 +3919,6 @@ void CreateXPMPieces() static char *xpmkind[] = { "ll", "ld", "dl", "dd" }; XpmColorSymbol symbols[4]; -#if 0 - /* Apparently some versions of Xpm don't define XpmFormat at all --tpm */ - if (appData.debugMode) { - fprintf(stderr, "XPM Library Version: %d.%d%c\n", - XpmFormat, XpmVersion, (char)('a' + XpmRevision - 1)); - } -#endif - /* The XSynchronize calls were copied from CreatePieces. Not sure if needed, but can't hurt */ XSynchronize(xDisplay, True); /* Work-around for xlib/xt buffering bug */ @@ -4155,14 +4148,7 @@ void ReadBitmap(pm, name, bits, wreq, hreq) return; } } - if (bits == NULL) { -#if 0 - fprintf(stderr, _("%s: No built-in bitmap for %s; giving up\n"), - programName, name); - exit(1); -#endif - ; // [HGM] bitmaps: make it non-fatal if we have no bitmap; - } else { + if (bits != NULL) { *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits, wreq, hreq); } @@ -5143,44 +5129,8 @@ void HandleUserMove(w, event, prms, nprms) String *prms; Cardinal *nprms; { - int x, y; - Boolean saveAnimate; - static int second = 0, promotionChoice = 0; - ChessMove moveType; - if (w != boardWidget || errorExitStatus != -1) return; - x = EventToSquare(event->xbutton.x, BOARD_WIDTH); - y = EventToSquare(event->xbutton.y, BOARD_HEIGHT); - if (!flipView && y >= 0) { - y = BOARD_HEIGHT - 1 - y; - } - if (flipView && x >= 0) { - x = BOARD_WIDTH - 1 - x; - } - - if(promotionChoice) { // we are waiting for a click to indicate promotion piece - if(event->type == ButtonRelease) return; // ignore upclick of click-click destination - promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel - if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y); - if(gameInfo.holdingsWidth && - (WhiteOnMove(currentMove) - ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0 - : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) { - // click in right holdings, for determining promotion piece - ChessSquare p = boards[currentMove][y][x]; - if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p); - if(p != EmptySquare) { - FinishMove(NormalMove, fromX, fromY, toX, toY, ToLower(PieceToChar(p))); - fromX = fromY = -1; - return; - } - } - DrawPosition(FALSE, boards[currentMove]); - return; - } - if (event->type == ButtonPress) ErrorPopDown(); - if (promotionUp) { if (event->type == ButtonPress) { XtPopdown(promotionShell); @@ -5193,137 +5143,9 @@ void HandleUserMove(w, event, prms, nprms) } } - /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */ - if(event->type == ButtonPress - && ( x == BOARD_LEFT-1 || x == BOARD_RGHT - || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize - || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) ) - return; - - if (fromX == -1) { - if (event->type == ButtonPress) { - /* First square, prepare to drag */ - if (OKToStartUserMove(x, y)) { - fromX = x; - fromY = y; - second = 0; - DragPieceBegin(event->xbutton.x, event->xbutton.y); - if (appData.highlightDragging) { - SetHighlights(x, y, -1, -1); - } - } - } - return; - } - - /* fromX != -1 */ - if (event->type == ButtonRelease && x == fromX && y == fromY) { - /* Click on single square in stead of drag-drop */ - DragPieceEnd(event->xbutton.x, event->xbutton.y); - if (appData.animateDragging) { - /* Undo animation damage if any */ - DrawPosition(FALSE, NULL); - } - if (second) { - /* Second up/down in same square; just abort move */ - second = 0; - fromX = fromY = -1; - ClearHighlights(); - gotPremove = 0; - ClearPremoveHighlights(); - } else { - /* First upclick in same square; start click-click mode */ - SetHighlights(x, y, -1, -1); - } - return; - } - - moveType = UserMoveTest(fromX, fromY, x, y, NULLCHAR, event->type == ButtonRelease); - - if (moveType == Comment) { // kludge for indicating capture-own on Press - /* Clicked again on same color piece -- changed his mind */ - /* note that re-clicking same square always hits same color piece */ - second = (x == fromX && y == fromY); - if (appData.highlightDragging) { - SetHighlights(x, y, -1, -1); - } else { - ClearHighlights(); - } - if (OKToStartUserMove(x, y)) { - fromX = x; - fromY = y; - DragPieceBegin(event->xbutton.x, event->xbutton.y); - } - return; - } - - if(moveType == AmbiguousMove) { // kludge to indicate edit-position move - fromX = fromY = -1; - ClearHighlights(); - DragPieceEnd(event->xbutton.x, event->xbutton.y); - DrawPosition(FALSE, boards[currentMove]); - return; - } - - /* Complete move; (x,y) is now different from (fromX, fromY) on both Press and Release */ - toX = x; - toY = y; - saveAnimate = appData.animate; - if (event->type == ButtonPress) { - /* Finish clickclick move */ - if (appData.animate || appData.highlightLastMove) { - SetHighlights(fromX, fromY, toX, toY); - } else { - ClearHighlights(); - } - } else { - /* Finish drag move */ - if (appData.highlightLastMove) { - SetHighlights(fromX, fromY, toX, toY); - } else { - ClearHighlights(); - } - DragPieceEnd(event->xbutton.x, event->xbutton.y); - /* Don't animate move and drag both */ - appData.animate = FALSE; - } - if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || - (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) && - appData.alwaysPromoteToQueen) { // promotion, but no choice - FinishMove(moveType, fromX, fromY, toX, toY, 'q'); - } else - if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) { - SetHighlights(fromX, fromY, toX, toY); - if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) { - // [HGM] super: promotion to captured piece selected from holdings - ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; - promotionChoice = TRUE; - // kludge follows to temporarily execute move on display, without promoting yet - boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank - boards[currentMove][toY][toX] = p; - DrawPosition(FALSE, boards[currentMove]); - boards[currentMove][fromY][fromX] = p; // take back, but display stays - boards[currentMove][toY][toX] = q; - DisplayMessage("Click in holdings to choose piece", ""); - return; - } - PromotionPopUp(); - goto skipClearingFrom; // the skipped stuff is done asynchronously by PromotionCallback - } else - if(moveType != ImpossibleMove) { // valid move, but no promotion - FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); - } else { // invalid move; could have set premove - ClearHighlights(); - } - if (!appData.highlightLastMove || gotPremove) ClearHighlights(); - if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY); - fromX = fromY = -1; -skipClearingFrom: - appData.animate = saveAnimate; - if (appData.animate || appData.animateDragging) { - /* Undo animation damage if needed */ - DrawPosition(FALSE, NULL); - } + // [HGM] mouse: the rest of the mouse handler is moved to the backend, and called here + if(event->type == ButtonPress) LeftClick(Press, event->xbutton.x, event->xbutton.y); + if(event->type == ButtonRelease) LeftClick(Release, event->xbutton.x, event->xbutton.y); } void AnimateUserMove (Widget w, XEvent * event, @@ -5377,12 +5199,8 @@ Widget CommentCreate(name, text, mutable, callback, lines) XtSetArg(args[j], XtNright, XtChainRight); j++; XtSetArg(args[j], XtNresizable, True); j++; XtSetArg(args[j], XtNwidth, bw_width); j++; /*force wider than buttons*/ -#if 0 - XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++; -#else /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */ XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; -#endif XtSetArg(args[j], XtNautoFill, True); j++; XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; edit = @@ -5535,12 +5353,8 @@ Widget MiscCreate(name, text, mutable, callback, lines) XtSetArg(args[j], XtNleft, XtChainLeft); j++; XtSetArg(args[j], XtNright, XtChainRight); j++; XtSetArg(args[j], XtNresizable, True); j++; -#if 0 - XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded); j++; -#else /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */ XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; -#endif XtSetArg(args[j], XtNautoFill, True); j++; XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; edit = @@ -5773,37 +5587,6 @@ void CommentPopUp(title, text) commentUp = True; } -void AnalysisPopUp(title, text) - char *title, *text; -{ - Arg args[16]; - int j; - Widget edit; - - if (analysisShell == NULL) { - analysisShell = MiscCreate(title, text, False, NULL, 4); - XtRealizeWidget(analysisShell); - CatchDeleteWindow(analysisShell, "AnalysisPopDown"); - - } else { - edit = XtNameToWidget(analysisShell, "*form.text"); - j = 0; - XtSetArg(args[j], XtNstring, text); j++; - XtSetValues(edit, args, j); - j = 0; - XtSetArg(args[j], XtNiconName, (XtArgVal) title); j++; - XtSetArg(args[j], XtNtitle, (XtArgVal) title); j++; - XtSetValues(analysisShell, args, j); - } - - if (!analysisUp) { - XtPopup(analysisShell, XtGrabNone); - } - XSync(xDisplay, False); - - analysisUp = True; -} - void CommentCallback(w, client_data, call_data) Widget w; XtPointer client_data, call_data; @@ -5842,16 +5625,6 @@ void CommentPopDown() commentUp = False; } -void AnalysisPopDown() -{ - if (!analysisUp) return; - XtPopdown(analysisShell); - XSync(xDisplay, False); - analysisUp = False; - if (appData.icsEngineAnalyze) ExitAnalyzeMode(); /* [DM] icsEngineAnalyze */ -} - - void FileNamePopUp(label, def, proc, openMode) char *label; char *def; @@ -6103,7 +5876,7 @@ void PromotionCallback(w, client_data, call_data) promoChar = ToLower(name[0]); } - FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar); + UserMoveEvent(fromX, fromY, toX, toY, promoChar); if (!appData.highlightLastMove || gotPremove) ClearHighlights(); if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY); @@ -6279,15 +6052,6 @@ void ModeHighlight() args, 1); if (appData.showButtonBar) { -#if 0 - if (pausing) { - XtSetArg(args[0], XtNbackground, buttonForegroundPixel); - XtSetArg(args[1], XtNforeground, buttonBackgroundPixel); - } else { - XtSetArg(args[0], XtNbackground, buttonBackgroundPixel); - XtSetArg(args[1], XtNforeground, buttonForegroundPixel); - } -#else /* Always toggle, don't set. Previous code messes up when invoked while the button is pressed, as releasing it toggles the state again. */ @@ -6300,7 +6064,6 @@ void ModeHighlight() XtSetArg(args[0], XtNbackground, oldfg); XtSetArg(args[1], XtNforeground, oldbg); } -#endif XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2); } } @@ -6333,7 +6096,6 @@ void ResetProc(w, event, prms, nprms) Cardinal *nprms; { ResetGameEvent(); - AnalysisPopDown(); } int LoadGamePopUp(f, gameNumber, title) @@ -7545,16 +7307,6 @@ void ShowThinkingProc(w, event, prms, nprms) appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent ShowThinkingEvent(); -#if 0 - // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human) - if (appData.showThinking) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"), - args, 1); -#endif } void HideThinkingProc(w, event, prms, nprms) @@ -8761,11 +8513,33 @@ int OutputToProcess(pr, message, count, outError) int count; int *outError; { + static int line = 0; ChildProc *cp = (ChildProc *) pr; int outCount; if (pr == NoProc) - outCount = fwrite(message, 1, count, stdout); + { + 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 + { + 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); + } + } + } else outCount = write(cp->fdTo, message, count); @@ -8985,12 +8759,7 @@ FrameDelay (time) delay.it_interval.tv_usec = delay.it_value.tv_usec = (time % 1000) * 1000; setitimer(ITIMER_REAL, &delay, NULL); -#if 0 - /* Ugh -- busy-wait! --tpm */ - while (frameWaiting); -#else while (frameWaiting) pause(); -#endif delay.it_interval.tv_sec = delay.it_value.tv_sec = 0; delay.it_interval.tv_usec = delay.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &delay, NULL); @@ -9420,7 +9189,7 @@ AnimateMove(board, fromX, fromY, toX, toY) damage[toY][toX] = True; } -static void +void DragPieceBegin(x, y) int x; int y; { @@ -9439,19 +9208,10 @@ DragPieceBegin(x, y) ScreenSquare(boardX, boardY, &corner, &color); player.startSquare = corner; player.startColor = color; -#if 0 - /* Start from exactly where the piece is. This can be confusing - if you start dragging far from the center of the square; most - or all of the piece can be over a different square from the one - the mouse pointer is in. */ - player.mouseDelta.x = x - corner.x; - player.mouseDelta.y = y - corner.y; -#else /* As soon as we start dragging, the piece will jump slightly to be centered over the mouse pointer. */ player.mouseDelta.x = squareSize/2; player.mouseDelta.y = squareSize/2; -#endif /* Initialise animation */ player.dragPiece = PieceForSquare(boardX, boardY); /* Sanity check */ @@ -9499,7 +9259,7 @@ DragPieceMove(x, y) #endif } -static void +void DragPieceEnd(x, y) int x; int y; { @@ -9553,3 +9313,38 @@ SetProgramStats( FrontEndProgramStats * stats ) // [HGM] done, but perhaps backend should call this directly? EngineOutputUpdate( stats ); } + +#include +int get_term_width() +{ + int fd, default_width; + + fd = STDIN_FILENO; + default_width = 79; // this is FICS default anyway... + +#if !defined(TIOCGWINSZ) && defined(TIOCGSIZE) + struct ttysize win; + if (!ioctl(fd, TIOCGSIZE, &win)) + default_width = win.ts_cols; +#elif defined(TIOCGWINSZ) + struct winsize win; + if (!ioctl(fd, TIOCGWINSZ, &win)) + default_width = win.ws_col; +#endif + return default_width; +} + +void update_ics_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; +} + +void NotifyFrontendLogin() +{ + update_ics_width(); +}