diff --git a/src/lib/internal.h b/src/lib/internal.h index 9c8c2bfb4..1ad7afee0 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -1131,8 +1131,6 @@ coerce_styles(FILE* out, const tinfo* ti, uint16_t* curstyle, uint16_t newstyle, unsigned* normalized){ *normalized = 0; // we never currently use sgr0 int ret = 0; - ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_BLINK, - get_escape(ti, ESCAPE_BLINK), get_escape(ti, ESCAPE_NOBLINK)); ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_BOLD, get_escape(ti, ESCAPE_BOLD), get_escape(ti, ESCAPE_NOBOLD)); ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_ITALIC, @@ -1179,38 +1177,39 @@ mouse_disable(FILE* out){ // our understanding of our horizontal location is faulty. // FIXME fall back to synthesized moves in the absence of capabilities (i.e. // textronix lacks cup; fake it with horiz+vert moves) -// if hardcursorpos is non-zero, we always perform a cup +// if hardcursorpos is non-zero, we always perform a cup. this is done when we +// don't know where the cursor currently is =]. static inline int goto_location(notcurses* nc, FILE* out, int y, int x){ //fprintf(stderr, "going to %d/%d from %d/%d hard: %u\n", y, x, nc->rstate.y, nc->rstate.x, hardcursorpos); int ret = 0; // if we don't have hpa, force a cup even if we're only 1 char away. the only - // terminal i know supporting cup sans hpa is vt100, and vt100 can suck it. + // TERM i know supporting cup sans hpa is vt100, and vt100 can suck it. // you can't use cuf for backwards moves anyway; again, vt100 can suck it. const char* hpa = get_escape(&nc->tcache, ESCAPE_HPA); if(nc->rstate.y == y && hpa && !nc->rstate.hardcursorpos){ // only need move x if(nc->rstate.x == x){ // needn't move shit return 0; } - const char* cuf1 = get_escape(&nc->tcache, ESCAPE_CUF1); - if(x == nc->rstate.x + 1 && cuf1){ - ret = term_emit(cuf1, out, false); - }else{ - ret = term_emit(tiparm(hpa, x), out, false); + if(term_emit(tiparm(hpa, x), out, false)){ + return -1; } }else{ // cup is required, no need to verify existence - ret = term_emit(tiparm(get_escape(&nc->tcache, ESCAPE_CUP), y, x), out, false); - nc->rstate.hardcursorpos = 0; + const char* cup = get_escape(&nc->tcache, ESCAPE_CUP); + if(term_emit(tiparm(cup, y, x), out, false)){ + return -1; + } } - nc->rstate.x = x; - nc->rstate.y = y; if(nc->rstate.logendy >= 0){ if(y > nc->rstate.logendy || (y == nc->rstate.logendy && x > nc->rstate.logendx)){ nc->rstate.logendy = y; nc->rstate.logendx = x; } } + nc->rstate.x = x; + nc->rstate.y = y; + nc->rstate.hardcursorpos = 0; return ret; } diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 61090a4df..f1ef3fa64 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1181,14 +1181,12 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ goto err; } } - const char* clearscr = get_escape(&ret->tcache, ESCAPE_CLEAR); - // perform an explicit clear if the alternate screen was requested - // (smcup *might* clear, but who knows, and might not have been + // perform an explicit clear since the alternate screen was requested + // (smcup *might* clear, but who knows? and it might not have been // available in any case). - if(!clearscr || term_emit(clearscr, ret->ttyfp, true)){ - // if we don't have a clear escape, clear via iterated writes - notcurses_refresh(ret, NULL, NULL); - } + notcurses_refresh(ret, NULL, NULL); + // no need to reestablish a preserved cursor -- that only affects the + // standard plane, not the physical cursor that was just disrupted. } } return ret; diff --git a/src/lib/render.c b/src/lib/render.c index 05eb0a3d0..9546c8654 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -1206,28 +1206,41 @@ notcurses_rasterize(notcurses* nc, ncpile* p, FILE* out){ return ret; } -// get the cursor to the upper-left corner by one means or another. will clear -// the screen if need be. +// get the cursor to the upper-left corner by one means or another, clearing +// the screen while doing so. static int -home_cursor(notcurses* nc, bool flush){ - int ret = -1; - const char* home = get_escape(&nc->tcache, ESCAPE_HOME); - if(home){ - ret = term_emit(home, nc->ttyfp, flush); - }else{ - const char* cup = get_escape(&nc->tcache, ESCAPE_CUP); - const char* clearscr = get_escape(&nc->tcache, ESCAPE_CLEAR); - if(cup){ - ret = term_emit(tiparm(cup, 1, 1), nc->ttyfp, flush); - }else if(clearscr){ - ret = term_emit(clearscr, nc->ttyfp, flush); +clear_and_home(notcurses* nc, tinfo* ti, FILE* fp, unsigned flush){ + // clear clears the screen and homes the cursor by itself + const char* clearscr = get_escape(ti, ESCAPE_CLEAR); + if(clearscr){ + if(term_emit(clearscr, fp, flush) == 0){ + goto success; } } - if(ret >= 0){ - nc->rstate.x = 0; - nc->rstate.y = 0; + const ncplane* stdn = notcurses_stdplane_const(nc); + // clearscr didn't fly. try scrolling everything off. first, go to the + // bottom of the screen, then write N newlines. + if(goto_location(nc, fp, ncplane_dim_y(stdn) - 1, 0)){ + return -1; } - return ret; + for(int y = 0 ; y < ncplane_dim_y(stdn) ; ++y){ + if(ncfputc('\n', fp) == EOF){ + return -1; + } + } + if(goto_location(nc, fp, 0, 0)){ + return -1; + } + if(flush){ + if(ncflush(fp)){ + return -1; + } + } + +success: + nc->rstate.x = 0; + nc->rstate.y = 0; + return 0; } int notcurses_refresh(notcurses* nc, int* restrict dimy, int* restrict dimx){ @@ -1237,7 +1250,7 @@ int notcurses_refresh(notcurses* nc, int* restrict dimy, int* restrict dimx){ if(nc->lfdimx == 0 || nc->lfdimy == 0){ return 0; } - if(home_cursor(nc, true)){ + if(clear_and_home(nc, &nc->tcache, nc->ttyfp, true)){ return -1; } ncpile p = {}; diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 917c5321e..9af057125 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -534,7 +534,6 @@ build_supported_styles(tinfo* ti){ { NCSTYLE_UNDERLINE, ESCAPE_SMUL, "smul", A_UNDERLINE }, { NCSTYLE_ITALIC, ESCAPE_SITM, "sitm", A_ITALIC }, { NCSTYLE_STRUCK, ESCAPE_SMXX, "smxx", 0 }, - { NCSTYLE_BLINK, ESCAPE_BLINK, "blink", A_BLINK }, { NCSTYLE_UNDERCURL, ESCAPE_SMULX, "Smulx", 0 }, { 0, 0, NULL, 0 } }; @@ -620,11 +619,9 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8, { ESCAPE_SITM, "sitm", }, { ESCAPE_RITM, "ritm", }, { ESCAPE_BOLD, "bold", }, - { ESCAPE_BLINK, "blink", }, { ESCAPE_CUD, "cud", }, { ESCAPE_CUU, "cuu", }, { ESCAPE_CUF, "cuf", }, - { ESCAPE_CUF1, "cuf1", }, { ESCAPE_CUB, "cub", }, { ESCAPE_INITC, "initc", }, { ESCAPE_GETM, "getm", }, @@ -636,7 +633,6 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8, { ESCAPE_SC, "sc", }, { ESCAPE_RC, "rc", }, { ESCAPE_CLEAR, "clear", }, - { ESCAPE_HOME, "home", }, { ESCAPE_OC, "oc", }, { ESCAPE_RMKX, "rmkx", }, { ESCAPE_DSRCPR, "u7", }, @@ -689,11 +685,6 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8, goto err; } } - if(get_escape(ti, ESCAPE_BLINK)){ - if(grow_esc_table(ti, "\e[25m", ESCAPE_NOBLINK, &tablelen, &tableused)){ - goto err; - } - } // if op is defined as ansi 39 + ansi 49, make the split definitions // available. this ought be asserted by extension capability "ax", but // no terminal i've found seems to do so. =[ diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index eb5563252..8fcf2570f 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -45,10 +45,7 @@ typedef enum { ESCAPE_CUF, // "cuf" move n cells forward (right) ESCAPE_BOLD, // "bold" enter bold mode ESCAPE_NOBOLD, // disable bold (ANSI but not terminfo, SGR 22) - ESCAPE_BLINK, // "blink" enter blink mode - ESCAPE_NOBLINK, // disable blink (ANSI but not terminfo, SGR 25) ESCAPE_CUD, // "cud" move n cells down - ESCAPE_CUF1, // "cuf1" move 1 cell forward (right) ESCAPE_SMKX, // "smkx" keypad_xmit (keypad transmit mode) ESCAPE_RMKX, // "rmkx" keypad_local ESCAPE_SMCUP, // "smcup" enter alternate screen @@ -62,7 +59,6 @@ typedef enum { ESCAPE_SC, // "sc" push the cursor onto the stack ESCAPE_RC, // "rc" pop the cursor off the stack ESCAPE_CLEAR, // "clear" clear screen and home cursor - ESCAPE_HOME, // "home" home cursor ESCAPE_INITC, // "initc" set up palette entry ESCAPE_GETM, // "getm" get mouse events ESCAPE_DSRCPR, // "u7" cursor position report