render: use unlocked stdio in render path

pull/151/head
nick black 5 years ago committed by Nick Black
parent c5acdaaef0
commit 91a7427689

@ -24,8 +24,6 @@
#include "version.h"
#include "egcpool.h"
#define ESC "\x1b"
// only one notcurses object can be the target of signal handlers, due to their
// process-wide nature.
static notcurses* _Atomic signal_nc = ATOMIC_VAR_INIT(NULL); // ugh
@ -901,16 +899,32 @@ int ncplane_default(ncplane* ncp, cell* c){
// 3 for foreground, 4 for background, ugh FIXME
static int
term_esc_rgb(FILE* out, int esc, unsigned r, unsigned g, unsigned b){
#define RGBESC1 ESC "["
term_esc_rgb(notcurses* nc __attribute__ ((unused)), FILE* out, int esc,
unsigned r, unsigned g, unsigned b){
// The correct way to do this is using tiparm+tputs, but doing so (at least
// as of terminfo 6.1.20191019) both emits ~3% more bytes for a run of 'rgb'
// and gives rise to some corrupted cells (possibly due to special handling of
// values < 256; I'm not at this time sure). So we just cons up our own.
/*if(esc == 4){
return term_emit("setab", tiparm(nc->setab, (int)((r << 16u) | (g << 8u) | b)), out, false);
}else if(esc == 3){
return term_emit("setaf", tiparm(nc->setaf, (int)((r << 16u) | (g << 8u) | b)), out, false);
}else{
return -1;
}*/
#define RGBESC1 "\x1b" "["
#define RGBESC2 "8;2;"
// rrr;ggg;bbbm
char rgbesc[] = RGBESC1 " " RGBESC2 " ";
int len = strlen(RGBESC1);
rgbesc[len++] = esc + '0';
rgbesc[len++] = esc;
len += strlen(RGBESC2);
if(r > 99){ rgbesc[len++] = r / 100 + '0'; }
if(r > 9){ rgbesc[len++] = (r % 100) / 10 + '0'; }
if(r > 99){
rgbesc[len++] = r / 100 + '0';
}
if(r > 9){
rgbesc[len++] = (r % 100) / 10 + '0';
}
rgbesc[len++] = (r % 10) + '0';
rgbesc[len++] = ';';
if(g > 99){ rgbesc[len++] = g / 100 + '0'; }
@ -923,7 +937,7 @@ term_esc_rgb(FILE* out, int esc, unsigned r, unsigned g, unsigned b){
rgbesc[len++] = 'm';
rgbesc[len] = '\0';
int w;
if((w = fprintf(out, "%.*s", len, rgbesc)) < len){
if((w = fputs_unlocked(rgbesc, out)) < len){
return -1;
}
return 0;
@ -937,7 +951,7 @@ term_bg_rgb8(notcurses* nc, FILE* out, unsigned r, unsigned g, unsigned b){
// we're also in that case working with hopefully more robust terminals.
// If it doesn't work, eh, it doesn't work. Fuck the world; save yourself.
if(nc->RGBflag){
return term_esc_rgb(out, 4, r, g, b);
return term_esc_rgb(nc, out, '4', r, g, b);
}else{
if(nc->setab == NULL){
return -1;
@ -962,7 +976,7 @@ term_fg_rgb8(notcurses* nc, FILE* out, unsigned r, unsigned g, unsigned b){
// we're also in that case working with hopefully more robust terminals.
// If it doesn't work, eh, it doesn't work. Fuck the world; save yourself.
if(nc->RGBflag){
return term_esc_rgb(out, 3, r, g, b);
return term_esc_rgb(nc, out, '3', r, g, b);
}else{
if(nc->setaf == NULL){
return -1;
@ -997,19 +1011,19 @@ term_putc(FILE* out, const ncplane* n, const cell* c){
if(cell_simple_p(c)){
if(c->gcluster == 0 || iscntrl(c->gcluster)){
// fprintf(stderr, "[ ]\n");
if(fputc(' ', out) == EOF){
if(fputc_unlocked(' ', out) == EOF){
return -1;
}
}else{
// fprintf(stderr, "[%c]\n", c->gcluster);
if(fputc(c->gcluster, out) == EOF){
if(fputc_unlocked(c->gcluster, out) == EOF){
return -1;
}
}
}else{
const char* ext = extended_gcluster(n, c);
// fprintf(stderr, "[%s]\n", ext);
if(fprintf(out, "%s", ext) < 0){ // FIXME check for short write?
if(fputs_unlocked(ext, out) < 0){ // FIXME check for short write?
return -1;
}
}

Loading…
Cancel
Save