diff --git a/src/lib/direct.cpp b/src/lib/direct.cpp index 67e00fa18..c33563d95 100644 --- a/src/lib/direct.cpp +++ b/src/lib/direct.cpp @@ -58,7 +58,7 @@ int ncdirect_cursor_up(ncdirect* nc, int num){ if(!nc->tcache.cuu){ return -1; } - return term_emit("cuu", tiparm(nc->tcache.cuu, num), nc->ttyfp, false); + return term_emit(tiparm(nc->tcache.cuu, num), nc->ttyfp, false); } int ncdirect_cursor_left(ncdirect* nc, int num){ @@ -68,7 +68,7 @@ int ncdirect_cursor_left(ncdirect* nc, int num){ if(!nc->tcache.cub){ return -1; } - return term_emit("cub", tiparm(nc->tcache.cub, num), nc->ttyfp, false); + return term_emit(tiparm(nc->tcache.cub, num), nc->ttyfp, false); } int ncdirect_cursor_right(ncdirect* nc, int num){ @@ -78,7 +78,7 @@ int ncdirect_cursor_right(ncdirect* nc, int num){ if(!nc->tcache.cuf){ // FIXME fall back to cuf1 return -1; } - return term_emit("cuf", tiparm(nc->tcache.cuf, num), nc->ttyfp, false); + return term_emit(tiparm(nc->tcache.cuf, num), nc->ttyfp, false); } int ncdirect_cursor_down(ncdirect* nc, int num){ @@ -88,14 +88,14 @@ int ncdirect_cursor_down(ncdirect* nc, int num){ if(!nc->tcache.cud){ return -1; } - return term_emit("cud", tiparm(nc->tcache.cud, num), nc->ttyfp, false); + return term_emit(tiparm(nc->tcache.cud, num), nc->ttyfp, false); } int ncdirect_clear(ncdirect* nc){ if(!nc->tcache.clearscr){ return -1; // FIXME scroll output off the screen } - return term_emit("clear", nc->tcache.clearscr, nc->ttyfp, true); + return term_emit(nc->tcache.clearscr, nc->ttyfp, true); } int ncdirect_dim_x(const ncdirect* nc){ @@ -126,14 +126,14 @@ int ncdirect_cursor_enable(ncdirect* nc){ if(!nc->tcache.cnorm){ return -1; } - return term_emit("cnorm", nc->tcache.cnorm, nc->ttyfp, true); + return term_emit(nc->tcache.cnorm, nc->ttyfp, true); } int ncdirect_cursor_disable(ncdirect* nc){ if(!nc->tcache.civis){ return -1; } - return term_emit("civis", nc->tcache.civis, nc->ttyfp, true); + return term_emit(nc->tcache.civis, nc->ttyfp, true); } int ncdirect_cursor_move_yx(ncdirect* n, int y, int x){ @@ -141,18 +141,18 @@ int ncdirect_cursor_move_yx(ncdirect* n, int y, int x){ if(!n->tcache.hpa){ return -1; } - return term_emit("hpa", tiparm(n->tcache.hpa, x), n->ttyfp, false); + return term_emit(tiparm(n->tcache.hpa, x), n->ttyfp, false); }else if(x == -1){ // keep column the same, vertical move only if(!n->tcache.vpa){ return -1; } - return term_emit("vpa", tiparm(n->tcache.vpa, y), n->ttyfp, false); + return term_emit(tiparm(n->tcache.vpa, y), n->ttyfp, false); } if(n->tcache.cup){ - return term_emit("cup", tiparm(n->tcache.cup, y, x), n->ttyfp, false); + return term_emit(tiparm(n->tcache.cup, y, x), n->ttyfp, false); }else if(n->tcache.vpa && n->tcache.hpa){ - if(term_emit("hpa", tiparm(n->tcache.hpa, x), n->ttyfp, false) == 0 && - term_emit("vpa", tiparm(n->tcache.vpa, y), n->ttyfp, false) == 0){ + if(term_emit(tiparm(n->tcache.hpa, x), n->ttyfp, false) == 0 && + term_emit(tiparm(n->tcache.vpa, y), n->ttyfp, false) == 0){ return 0; } } @@ -362,14 +362,14 @@ int ncdirect_cursor_push(ncdirect* n){ if(n->tcache.sc == nullptr){ return -1; } - return term_emit("sc", n->tcache.sc, n->ttyfp, false); + return term_emit(n->tcache.sc, n->ttyfp, false); } int ncdirect_cursor_pop(ncdirect* n){ if(n->tcache.rc == nullptr){ return -1; } - return term_emit("rc", n->tcache.rc, n->ttyfp, false); + return term_emit(n->tcache.rc, n->ttyfp, false); } static inline int @@ -542,14 +542,14 @@ int ncdirect_set_fg_palindex(ncdirect* nc, int pidx){ if(channels_set_fg_palindex(&nc->channels, pidx) < 0){ return -1; } - return term_emit("setaf", tiparm(nc->tcache.setaf, pidx), nc->ttyfp, false); + return term_emit(tiparm(nc->tcache.setaf, pidx), nc->ttyfp, false); } int ncdirect_set_bg_palindex(ncdirect* nc, int pidx){ if(channels_set_bg_palindex(&nc->channels, pidx) < 0){ return -1; } - return term_emit("setab", tiparm(nc->tcache.setab, pidx), nc->ttyfp, false); + return term_emit(tiparm(nc->tcache.setab, pidx), nc->ttyfp, false); } int ncdirect_vprintf_aligned(ncdirect* n, int y, ncalign_e align, const char* fmt, va_list ap){ @@ -600,17 +600,17 @@ ncdirect_stop_minimal(void* vnc){ if(nc->initialized_readline){ rl_deprep_terminal(); } - if(nc->tcache.op && term_emit("op", nc->tcache.op, nc->ttyfp, true)){ + if(nc->tcache.op && term_emit(nc->tcache.op, nc->ttyfp, true)){ ret = -1; } - if(nc->tcache.sgr0 && term_emit("sgr0", nc->tcache.sgr0, nc->ttyfp, true)){ + if(nc->tcache.sgr0 && term_emit(nc->tcache.sgr0, nc->ttyfp, true)){ ret = -1; } - if(nc->tcache.oc && term_emit("oc", nc->tcache.oc, nc->ttyfp, true)){ + if(nc->tcache.oc && term_emit(nc->tcache.oc, nc->ttyfp, true)){ ret = -1; } if(nc->ctermfd >= 0){ - if(nc->tcache.cnorm && tty_emit("cnorm", nc->tcache.cnorm, nc->ctermfd)){ + if(nc->tcache.cnorm && tty_emit(nc->tcache.cnorm, nc->ctermfd)){ ret = -1; } ret |= tcsetattr(nc->ctermfd, TCSANOW, &nc->tpreserved); @@ -709,16 +709,16 @@ static inline int ncdirect_style_emit(ncdirect* n, unsigned stylebits, FILE* out){ int r = -1; if(stylebits == 0 && n->tcache.sgr0){ - r = term_emit("sgr0", n->tcache.sgr0, n->ttyfp, false); + r = term_emit(n->tcache.sgr0, n->ttyfp, false); }else if(n->tcache.sgr){ - r = term_emit("sgr", tiparm(n->tcache.sgr, stylebits & NCSTYLE_STANDOUT, - stylebits & NCSTYLE_UNDERLINE, - stylebits & NCSTYLE_REVERSE, - stylebits & NCSTYLE_BLINK, - stylebits & NCSTYLE_DIM, - stylebits & NCSTYLE_BOLD, - stylebits & NCSTYLE_INVIS, - stylebits & NCSTYLE_PROTECT, 0), out, false); + r = term_emit(tiparm(n->tcache.sgr, stylebits & NCSTYLE_STANDOUT, + stylebits & NCSTYLE_UNDERLINE, + stylebits & NCSTYLE_REVERSE, + stylebits & NCSTYLE_BLINK, + stylebits & NCSTYLE_DIM, + stylebits & NCSTYLE_BOLD, + stylebits & NCSTYLE_INVIS, + stylebits & NCSTYLE_PROTECT, 0), out, false); } // sgr resets colors, so set them back up if not defaults if(r == 0){ @@ -809,10 +809,10 @@ int ncdirect_set_fg_default(ncdirect* nc){ return 0; } if(nc->tcache.fgop){ - if(term_emit("fgop", nc->tcache.fgop, nc->ttyfp, false)){ + if(term_emit(nc->tcache.fgop, nc->ttyfp, false)){ return -1; } - }else if(term_emit("op", nc->tcache.op, nc->ttyfp, false) == 0){ + }else if(term_emit(nc->tcache.op, nc->ttyfp, false) == 0){ if(!ncdirect_bg_default_p(nc)){ if(ncdirect_set_bg_rgb(nc, channels_bg_rgb(nc->channels))){ return -1; @@ -828,10 +828,10 @@ int ncdirect_set_bg_default(ncdirect* nc){ return 0; } if(nc->tcache.bgop){ - if(term_emit("bgop", nc->tcache.bgop, nc->ttyfp, false)){ + if(term_emit(nc->tcache.bgop, nc->ttyfp, false)){ return -1; } - }else if(term_emit("op", nc->tcache.op, nc->ttyfp, false) == 0){ + }else if(term_emit(nc->tcache.op, nc->ttyfp, false) == 0){ if(!ncdirect_fg_default_p(nc)){ if(ncdirect_set_fg_rgb(nc, channels_fg_rgb(nc->channels))){ return -1; diff --git a/src/lib/internal.h b/src/lib/internal.h index 98d92a1af..4e23be6f7 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -505,7 +505,7 @@ rgb_greyscale(int r, int g, int b){ } static inline int -tty_emit(const char* name __attribute__ ((unused)), const char* seq, int fd){ +tty_emit(const char* seq, int fd){ if(!seq){ return -1; } @@ -523,27 +523,25 @@ tty_emit(const char* name __attribute__ ((unused)), const char* seq, int fd){ } }while(written < slen); if(written < slen){ -//fprintf(stderr, "Error emitting %zub %s escape (%s)\n", strlen(seq), name, strerror(errno)); +//fprintf(stderr, "Error emitting %zub escape (%s)\n", strlen(seq), strerror(errno)); return -1; } return 0; } static inline int -term_emit(const char* name __attribute__ ((unused)), const char* seq, - FILE* out, bool flush){ +term_emit(const char* seq, FILE* out, bool flush){ if(!seq){ return -1; } if(fputs(seq, out) == EOF){ -//fprintf(stderr, "Error emitting %zub %s escape (%s)\n", strlen(seq), name, strerror(errno)); +//fprintf(stderr, "Error emitting %zub escape (%s)\n", strlen(seq), strerror(errno)); return -1; } if(flush){ while(fflush(out) == EOF){ if(errno != EAGAIN){ - fprintf(stderr, "Error flushing after %zub %s sequence (%s)\n", - strlen(seq), name, strerror(errno)); + fprintf(stderr, "Error flushing after %zub sequence (%s)\n", strlen(seq), strerror(errno)); return -1; } } @@ -556,7 +554,7 @@ term_bg_palindex(const notcurses* nc, FILE* out, unsigned pal){ if(nc->tcache.setab == NULL){ return 0; } - return term_emit("setab", tiparm(nc->tcache.setab, pal), out, false); + return term_emit(tiparm(nc->tcache.setab, pal), out, false); } static inline int @@ -564,7 +562,7 @@ term_fg_palindex(const notcurses* nc, FILE* out, unsigned pal){ if(nc->tcache.setaf == NULL){ return 0; } - return term_emit("setaf", tiparm(nc->tcache.setaf, pal), out, false); + return term_emit(tiparm(nc->tcache.setaf, pal), out, false); } static inline const char* diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index f96712817..e1857fe26 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -39,13 +39,13 @@ void notcurses_version_components(int* major, int* minor, int* patch, int* tweak static int reset_term_attributes(notcurses* nc){ int ret = 0; - if(nc->tcache.op && term_emit("op", nc->tcache.op, nc->ttyfp, false)){ + if(nc->tcache.op && term_emit(nc->tcache.op, nc->ttyfp, false)){ ret = -1; } - if(nc->tcache.sgr0 && term_emit("sgr0", nc->tcache.sgr0, nc->ttyfp, false)){ + if(nc->tcache.sgr0 && term_emit(nc->tcache.sgr0, nc->ttyfp, false)){ ret = -1; } - if(nc->tcache.oc && term_emit("oc", nc->tcache.oc, nc->ttyfp, true)){ + if(nc->tcache.oc && term_emit(nc->tcache.oc, nc->ttyfp, true)){ ret = -1; } ret |= notcurses_mouse_disable(nc); @@ -63,10 +63,10 @@ notcurses_stop_minimal(void* vnc){ // they apply to the screen (alternate or otherwise) we're actually using. ret |= reset_term_attributes(nc); if(nc->ttyfd >= 0){ - if(nc->tcache.rmcup && tty_emit("rmcup", nc->tcache.rmcup, nc->ttyfd)){ + if(nc->tcache.rmcup && tty_emit(nc->tcache.rmcup, nc->ttyfd)){ ret = -1; } - if(nc->tcache.cnorm && tty_emit("cnorm", nc->tcache.cnorm, nc->ttyfd)){ + if(nc->tcache.cnorm && tty_emit(nc->tcache.cnorm, nc->ttyfd)){ ret = -1; } ret |= tcsetattr(nc->ttyfd, TCSANOW, &nc->tpreserved); @@ -811,7 +811,7 @@ init_banner(const notcurses* nc){ fprintf(stderr, "\n Warning! Encoding is not UTF-8; output may be degraded.\n"); } if(nc->tcache.sgr0){ - term_emit("sgr0", nc->tcache.sgr0, stderr, true); + term_emit(nc->tcache.sgr0, stderr, true); } } } @@ -1050,11 +1050,11 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ goto err; } if(ret->ttyfd >= 0){ - if(ret->tcache.smkx && tty_emit("smkx", ret->tcache.smkx, ret->ttyfd)){ + if(ret->tcache.smkx && tty_emit(ret->tcache.smkx, ret->ttyfd)){ free_plane(ret->stdplane); goto err; } - if(ret->tcache.civis && tty_emit("civis", ret->tcache.civis, ret->ttyfd)){ + if(ret->tcache.civis && tty_emit(ret->tcache.civis, ret->ttyfd)){ free_plane(ret->stdplane); goto err; } @@ -1068,19 +1068,19 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ // flush on the switch to alternate screen, lest initial output be swept away if(ret->ttyfd >= 0){ if(ret->tcache.smcup){ - if(tty_emit("smcup", ret->tcache.smcup, ret->ttyfd)){ + if(tty_emit(ret->tcache.smcup, ret->ttyfd)){ free_plane(ret->stdplane); goto err; } // explicit clear even though smcup *might* clear - if(tty_emit("clear", ret->tcache.clearscr, ret->ttyfd)){ + if(tty_emit(ret->tcache.clearscr, ret->ttyfd)){ notcurses_refresh(ret, NULL, NULL); } }else if(!(opts->flags & NCOPTION_NO_ALTERNATE_SCREEN)){ // if they expected the alternate screen, but we didn't have one to // offer, at least clear the screen. try using "clear"; if that doesn't // fly, use notcurses_refresh() to force a clearing via iterated writes. - if(tty_emit("clear", ret->tcache.clearscr, ret->ttyfd)){ + if(tty_emit(ret->tcache.clearscr, ret->ttyfd)){ notcurses_refresh(ret, NULL, NULL); } } @@ -1142,6 +1142,12 @@ int notcurses_stop(notcurses* nc){ if(nc->rstate.mstreamfp){ fclose(nc->rstate.mstreamfp); } + // if we were not using the alternate screen, our cursor's wherever we last + // wrote. move it to the bottom left of the screen. + if(!nc->tcache.smcup){ + tty_emit(tiparm(nc->tcache.hpa, 0), nc->ttyfd); + tty_emit(tiparm(nc->tcache.vpa, nc->lfdimy - 1), nc->ttyfd); + } if(nc->ttyfd >= 0){ ret |= close(nc->ttyfd); } @@ -2026,7 +2032,7 @@ ncplane* ncplane_above(ncplane* n){ #define SET_SGR_MODE_MOUSE "1006" int notcurses_mouse_enable(notcurses* n){ if(n->ttyfd >= 0){ - return tty_emit("mouse", ESC "[?" SET_BTN_EVENT_MOUSE ";" + return tty_emit(ESC "[?" SET_BTN_EVENT_MOUSE ";" /*SET_FOCUS_EVENT_MOUSE ";" */SET_SGR_MODE_MOUSE "h", n->ttyfd); } @@ -2037,7 +2043,7 @@ int notcurses_mouse_enable(notcurses* n){ // the sequences 1000 etc? int notcurses_mouse_disable(notcurses* n){ if(n->ttyfd >= 0){ - return tty_emit("mouse", ESC "[?" SET_BTN_EVENT_MOUSE ";" + return tty_emit(ESC "[?" SET_BTN_EVENT_MOUSE ";" /*SET_FOCUS_EVENT_MOUSE ";" */SET_SGR_MODE_MOUSE "l", n->ttyfd); } diff --git a/src/lib/render.c b/src/lib/render.c index 9bcd5696b..75d26adad 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -609,11 +609,11 @@ int term_setstyle(FILE* out, unsigned cur, unsigned targ, unsigned stylebit, if(curon != targon){ if(targon){ if(ton){ - ret = term_emit("ton", ton, out, false); + ret = term_emit(ton, out, false); } }else{ if(toff){ // how did this happen? we can turn it on, but not off? - ret = term_emit("toff", toff, out, false); + ret = term_emit(toff, out, false); } } } @@ -640,18 +640,18 @@ term_setstyles(FILE* out, uint32_t* curattr, const nccell* c, bool* normalized, *normalized = true; // FIXME this is pretty conservative // if everything's 0, emit the shorter sgr0 if(sgr0 && ((cellattr & NCSTYLE_MASK) == 0)){ - if(term_emit("sgr0", sgr0, out, false) < 0){ + if(term_emit(sgr0, out, false) < 0){ ret = -1; } - }else if(term_emit("sgr", tiparm(sgr, cellattr & NCSTYLE_STANDOUT, - cellattr & NCSTYLE_UNDERLINE, - cellattr & NCSTYLE_REVERSE, - cellattr & NCSTYLE_BLINK, - cellattr & NCSTYLE_DIM, - cellattr & NCSTYLE_BOLD, - cellattr & NCSTYLE_INVIS, - cellattr & NCSTYLE_PROTECT, 0), - out, false) < 0){ + }else if(term_emit(tiparm(sgr, cellattr & NCSTYLE_STANDOUT, + cellattr & NCSTYLE_UNDERLINE, + cellattr & NCSTYLE_REVERSE, + cellattr & NCSTYLE_BLINK, + cellattr & NCSTYLE_DIM, + cellattr & NCSTYLE_BOLD, + cellattr & NCSTYLE_INVIS, + cellattr & NCSTYLE_PROTECT, 0), + out, false) < 0){ ret = -1; } // sgr will blow away italics/struck if they were set beforehand @@ -755,9 +755,9 @@ term_bg_rgb8(bool RGBflag, const char* setab, int colors, FILE* out, // a single screen, start... combining close ones? For 8-color mode, simple // interpolation. I have no idea what to do for 88 colors. FIXME if(colors >= 256){ - return term_emit("setab", tiparm(setab, rgb_quantize_256(r, g, b)), out, false); + return term_emit(tiparm(setab, rgb_quantize_256(r, g, b)), out, false); }else if(colors >= 8){ - return term_emit("setab", tiparm(setab, rgb_quantize_8(r, g, b)), out, false); + return term_emit(tiparm(setab, rgb_quantize_8(r, g, b)), out, false); } } return 0; @@ -782,9 +782,9 @@ term_fg_rgb8(bool RGBflag, const char* setaf, int colors, FILE* out, // a single screen, start... combining close ones? For 8-color mode, simple // interpolation. I have no idea what to do for 88 colors. FIXME if(colors >= 256){ - return term_emit("setaf", tiparm(setaf, rgb_quantize_256(r, g, b)), out, false); + return term_emit(tiparm(setaf, rgb_quantize_256(r, g, b)), out, false); }else if(colors >= 8){ - return term_emit("setaf", tiparm(setaf, rgb_quantize_8(r, g, b)), out, false); + return term_emit(tiparm(setaf, rgb_quantize_8(r, g, b)), out, false); } } return 0; @@ -802,7 +802,7 @@ update_palette(notcurses* nc, FILE* out){ r = r * 1000 / 255; g = g * 1000 / 255; b = b * 1000 / 255; - term_emit("initc", tiparm(nc->tcache.initc, damageidx, r, g, b), out, false); + term_emit(tiparm(nc->tcache.initc, damageidx, r, g, b), out, false); nc->palette_damage[damageidx] = false; } } @@ -827,13 +827,13 @@ goto_location(notcurses* nc, FILE* out, int y, int x){ return 0; } if(x == nc->rstate.x + 1 && nc->tcache.cuf1){ - ret = term_emit("cuf1", nc->tcache.cuf1, out, false); + ret = term_emit(nc->tcache.cuf1, out, false); }else{ - ret = term_emit("hpa", tiparm(nc->tcache.hpa, x), out, false); + ret = term_emit(tiparm(nc->tcache.hpa, x), out, false); } }else{ // cup is required, no need to check for existence - ret = term_emit("cup", tiparm(nc->tcache.cup, y, x), out, false); + ret = term_emit(tiparm(nc->tcache.cup, y, x), out, false); } if(ret == 0){ nc->rstate.x = x; @@ -855,7 +855,7 @@ raster_defaults(notcurses* nc, bool fgdef, bool bgdef, FILE* out){ ++nc->stats.defaultelisions; return 0; }else if((mustsetfg && mustsetbg) || !nc->tcache.fgop){ - if(term_emit("op", nc->tcache.op, out, false)){ + if(term_emit(nc->tcache.op, out, false)){ return -1; } nc->rstate.fgdefelidable = true; @@ -865,14 +865,14 @@ raster_defaults(notcurses* nc, bool fgdef, bool bgdef, FILE* out){ nc->rstate.fgpalelidable = false; nc->rstate.bgpalelidable = false; }else if(mustsetfg){ - if(term_emit("fgop", nc->tcache.fgop, out, false)){ + if(term_emit(nc->tcache.fgop, out, false)){ return -1; } nc->rstate.fgdefelidable = true; nc->rstate.fgelidable = false; nc->rstate.fgpalelidable = false; }else{ - if(term_emit("bgop", nc->tcache.bgop, out, false)){ + if(term_emit(nc->tcache.bgop, out, false)){ return -1; } nc->rstate.bgdefelidable = true; @@ -1089,11 +1089,11 @@ static int home_cursor(notcurses* nc, bool flush){ int ret = -1; if(nc->tcache.home){ - ret = term_emit("home", nc->tcache.home, nc->ttyfp, flush); + ret = term_emit(nc->tcache.home, nc->ttyfp, flush); }else if(nc->tcache.cup){ - ret = term_emit("cup", tiparm(nc->tcache.cup, 1, 1), nc->ttyfp, flush); + ret = term_emit(tiparm(nc->tcache.cup, 1, 1), nc->ttyfp, flush); }else if(nc->tcache.clearscr){ - ret = term_emit("clear", nc->tcache.clearscr, nc->ttyfp, flush); + ret = term_emit(nc->tcache.clearscr, nc->ttyfp, flush); } if(ret >= 0){ nc->rstate.x = 0; @@ -1360,7 +1360,7 @@ int notcurses_cursor_enable(notcurses* nc, int y, int x){ nc->cursorx = x; return 0; } - if(tty_emit("cnorm", nc->tcache.cnorm, nc->ttyfd) || fflush(nc->ttyfp) == EOF){ + if(tty_emit(nc->tcache.cnorm, nc->ttyfd) || fflush(nc->ttyfp) == EOF){ return -1; } nc->cursory = y; @@ -1375,7 +1375,7 @@ int notcurses_cursor_disable(notcurses* nc){ } if(nc->ttyfd >= 0){ if(nc->tcache.civis){ - if(!tty_emit("civis", nc->tcache.civis, nc->ttyfd) && !fflush(nc->ttyfp)){ + if(!tty_emit(nc->tcache.civis, nc->ttyfd) && !fflush(nc->ttyfp)){ nc->cursory = -1; nc->cursorx = -1; return 0;