yank locate_cursor_early() #1692

pull/1923/head
nick black 3 years ago committed by nick black
parent 85e55de569
commit 73324ce2a4

@ -179,6 +179,75 @@ int ncdirect_cursor_disable(ncdirect* nc){
return -1;
}
static int
cursor_yx_get(int ttyfd, const char* u7, int* y, int* x){
if(tty_emit(u7, ttyfd)){
return -1;
}
bool done = false;
enum { // what we expect now
CURSOR_ESC, // 27 (0x1b)
CURSOR_LSQUARE,
CURSOR_ROW, // delimited by a semicolon
CURSOR_COLUMN,
CURSOR_R,
} state = CURSOR_ESC;
int row = 0, column = 0;
int r;
char in;
do{
while((r = read(ttyfd, &in, 1)) == 1){
bool valid = false;
switch(state){
case CURSOR_ESC: valid = (in == NCKEY_ESC); state = CURSOR_LSQUARE; break;
case CURSOR_LSQUARE: valid = (in == '['); state = CURSOR_ROW; break;
case CURSOR_ROW:
if(isdigit(in)){
row *= 10;
row += in - '0';
valid = true;
}else if(in == ';'){
state = CURSOR_COLUMN;
valid = true;
}
break;
case CURSOR_COLUMN:
if(isdigit(in)){
column *= 10;
column += in - '0';
valid = true;
}else if(in == 'R'){
state = CURSOR_R;
valid = true;
}
break;
case CURSOR_R: default: // logical error, whoops
break;
}
if(!valid){
logerror("Unexpected result (%c, %d) from terminal\n", in, in);
break;
}
if(state == CURSOR_R){
done = true;
break;
}
}
// need to loop 0 to handle slow terminals, see for instance screen =[
}while(!done && (r >= 0 || (errno == EINTR || errno == EAGAIN || errno == EBUSY)));
if(!done){
logerror("Error reading cursor location\n");
return -1;
}
if(y){
*y = row;
}
if(x){
*x = column;
}
return 0;
}
// if we're lacking hpa/vpa, *and* -1 is passed for one of x/y, *and* we've
// not got a real ctermfd, we're pretty fucked. we just punt and substitute
// 0 for that case, which hopefully only happens when running headless unit

@ -1169,8 +1169,8 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
goto err;
}
if(ret->rstate.logendy >= 0){ // if either is set, both are
if(!ret->suppress_banner){
if(locate_cursor_early(ret, &ret->rstate.logendy, &ret->rstate.logendx)){
if(!ret->suppress_banner && ret->ttyfd >= 0){
if(locate_cursor(&ret->tcache, ret->ttyfd, &ret->rstate.logendy, &ret->rstate.logendx)){
free_plane(ret->stdplane);
goto err;
}

@ -771,74 +771,6 @@ char* termdesc_longterm(const tinfo* ti){
return ret;
}
int cursor_yx_get(int ttyfd, const char* u7, int* y, int* x){
if(tty_emit(u7, ttyfd)){
return -1;
}
bool done = false;
enum { // what we expect now
CURSOR_ESC, // 27 (0x1b)
CURSOR_LSQUARE,
CURSOR_ROW, // delimited by a semicolon
CURSOR_COLUMN,
CURSOR_R,
} state = CURSOR_ESC;
int row = 0, column = 0;
int r;
char in;
do{
while((r = read(ttyfd, &in, 1)) == 1){
bool valid = false;
switch(state){
case CURSOR_ESC: valid = (in == NCKEY_ESC); state = CURSOR_LSQUARE; break;
case CURSOR_LSQUARE: valid = (in == '['); state = CURSOR_ROW; break;
case CURSOR_ROW:
if(isdigit(in)){
row *= 10;
row += in - '0';
valid = true;
}else if(in == ';'){
state = CURSOR_COLUMN;
valid = true;
}
break;
case CURSOR_COLUMN:
if(isdigit(in)){
column *= 10;
column += in - '0';
valid = true;
}else if(in == 'R'){
state = CURSOR_R;
valid = true;
}
break;
case CURSOR_R: default: // logical error, whoops
break;
}
if(!valid){
logerror("Unexpected result (%c, %d) from terminal\n", in, in);
break;
}
if(state == CURSOR_R){
done = true;
break;
}
}
// need to loop 0 to handle slow terminals, see for instance screen =[
}while(!done && (r >= 0 || (errno == EINTR || errno == EAGAIN || errno == EBUSY)));
if(!done){
logerror("Error reading cursor location\n");
return -1;
}
if(y){
*y = row;
}
if(x){
*x = column;
}
return 0;
}
// send a u7 request, and wait until we have a cursor report
int locate_cursor(tinfo* ti, int fd, int* cursor_y, int* cursor_x){
if(fd < 0){
@ -874,23 +806,3 @@ int locate_cursor(tinfo* ti, int fd, int* cursor_y, int* cursor_x){
}
return 0;
}
int locate_cursor_early(struct notcurses* nc, int* cursor_y, int* cursor_x){
int ret = 0;
if(nc->ttyfd >= 0){
const char* u7 = get_escape(&nc->tcache, ESCAPE_DSRCPR);
// FIXME ought check for cursor inversion!
ret = cursor_yx_get(nc->ttyfd, u7, cursor_y, cursor_x);
if(ret == 0){
if(nc->tcache.inverted_cursor){
int tmp = *cursor_y;
*cursor_y = *cursor_x;
*cursor_x = tmp;
}
// we use 0-based coordinates, but known terminals use 1-based coordinates
--*cursor_y;
--*cursor_x;
}
}
return ret;
}

@ -213,11 +213,7 @@ void free_terminfo_cache(tinfo* ti);
// return a heap-allocated copy of termname + termversion
char* termdesc_longterm(const tinfo* ti);
// get the cursor location early (after interrogate_terminfo(), but before
// handing control back to the user). blocking call. FIXME this should go away
// once we have proper input handling that separates out control sequences.
int locate_cursor_early(struct notcurses* nc, int* cursor_y, int* cursor_x);
int cursor_yx_get(int ttyfd, const char* u7, int* y, int* x);
int locate_cursor(tinfo* ti, int fd, int* cursor_y, int* cursor_x);
#ifdef __cplusplus
}

Loading…
Cancel
Save