X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=80e622e4ebaa48665943f4fb4616b3dedb9aad9f;hb=1f84be6944ee48b72a33cf064661fa1a2129b885;hp=849ab40b71283d26d9c2443db6299f507d38bea9;hpb=0ea1b434ac6becf79c75d85ba27de5b89666a7c3;p=xboard.git diff --git a/xboard.c b/xboard.c index 849ab40..80e622e 100644 --- a/xboard.c +++ b/xboard.c @@ -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" @@ -467,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 */ @@ -502,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; @@ -1060,8 +1079,9 @@ char globalTranslations[] = \"Send to second chess program:\",,2) \n"; char boardTranslations[] = - ": HandleUserMove() \n \ - : HandleUserMove() \n \ + ": HandleUserMove(0) \n \ + Shift: HandleUserMove(1) \n \ + : HandleUserMove(0) \n \ : AnimateUserMove() \n \ : HandlePV() \n \ : PieceMenuPopup(menuB) \n \ @@ -1450,7 +1470,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 @@ -1584,6 +1604,7 @@ void PopUpStartupDialog() { // start menu not implemented in XBoard } + char * ConvertToLine(int argc, char **argv) { @@ -1591,14 +1612,17 @@ 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); @@ -2591,6 +2621,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) @@ -2637,22 +2674,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) { - safeStrCpy(buf, p, sizeof(buf)/sizeof(buf[0]) ); - strcat(buf, "/"); - strcat(buf, appData.icsLogon); + 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 @@ -3002,7 +3050,7 @@ 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); @@ -3502,12 +3550,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]; } } @@ -3530,13 +3578,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]; } } @@ -3558,11 +3606,11 @@ void ReadBitmap(pm, name, bits, wreq, hreq) if (*appData.bitmapDirectory != NULLCHAR) { safeStrCpy(fullname, appData.bitmapDirectory, sizeof(fullname)/sizeof(fullname[0]) ); - strcat(fullname, "/"); - strcat(fullname, name); - errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname, - &w, &h, pm, &x_hot, &y_hot); - fprintf(stderr, "load %s\n", name); + 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: @@ -3680,7 +3728,7 @@ Widget CreateMenuBar(mb) while (mb->name != NULL) { safeStrCpy(menuName, "menu", sizeof(menuName)/sizeof(menuName[0]) ); - strcat(menuName, mb->name); + strncat(menuName, mb->name, MSG_SIZ - strlen(menuName) - 1); j = 0; XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++; if (tinyLayout) { @@ -4168,6 +4216,7 @@ static void colorDrawPieceImage(piece, square_color, x, y, dest) } break; } + if(appData.upsideDown && flipView) kind ^= 2; // swap white and black pieces XCopyArea(xDisplay, xpmPieceBitmap[kind][piece], dest, wlPieceGC, 0, 0, squareSize, squareSize, x, y); @@ -4487,7 +4536,7 @@ void XDrawPosition(w, repaint, board) if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up if (board == NULL) { - if (!lastBoardValid) return; + if (!lastBoardValid[nr]) return; board = lastBoard[nr]; } if (!lastBoardValid[nr] || (nr == 0 && lastFlipView != flipView)) { @@ -4603,6 +4652,7 @@ void HandleUserMove(w, event, prms, nprms) Cardinal *nprms; { if (w != boardWidget || errorExitStatus != -1) return; + if(nprms) shiftKey = !strcmp(prms[0], "1"); if (promotionUp) { if (event->type == ButtonPress) { @@ -5135,13 +5185,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 @@ -5149,8 +5192,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: ", - def, openMode, NULL, &name)) - (void) (*fileProc)(f, index=0, name); + def, openMode, NULL, &name)) + (void) (*fileProc)(f, index=0, name); } } @@ -5991,7 +6034,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) { @@ -7279,9 +7322,9 @@ void AskQuestionReplyAction(w, event, prms, nprms) reply = XawDialogGetValueString(w = XtParent(w)); safeStrCpy(buf, pendingReplyPrefix, sizeof(buf)/sizeof(buf[0]) ); - if (*buf) strcat(buf, " "); - strcat(buf, reply); - strcat(buf, "\n"); + 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(); @@ -7433,18 +7476,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); @@ -7713,11 +7756,11 @@ DisplayTimerLabel(w, color, timer, highlight) 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) { @@ -8066,16 +8109,98 @@ 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, check special case for login and password */ + 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 + } } @@ -8131,28 +8256,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); @@ -8612,6 +8745,7 @@ OverlayPiece(piece, clip, outline, dest) kind = 0; else kind = 2; + if(appData.upsideDown && flipView) kind ^= 2; XCopyArea(xDisplay, xpmPieceBitmap[kind][piece], dest, clip, 0, 0, squareSize, squareSize, @@ -8940,17 +9074,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