|
|
|
@ -433,195 +433,3 @@ err:
|
|
|
|
|
free(ti->esctable);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// FIXME need unit tests on this
|
|
|
|
|
// FIXME can read a character not intended for it
|
|
|
|
|
// we'll get a trailing Device Attributes response, because we write
|
|
|
|
|
// XTSMGRAPHICS followed by a DA query, in case the former isn't supported
|
|
|
|
|
// (we'd otherwise hang looking for input).
|
|
|
|
|
static int
|
|
|
|
|
read_xtsmgraphics_reply(int fd, int* val2){
|
|
|
|
|
char in;
|
|
|
|
|
// return is of the form CSI ? Pi ; Ps ; Pv S
|
|
|
|
|
// Pi: 1 color registers, 2 sixel, 3 regis
|
|
|
|
|
// Pa: 1 read, 2 reset, 3 set to Pv, 4 read maximum
|
|
|
|
|
// Pv: n for color registers, width;height for geometry
|
|
|
|
|
// Ps: 0 success, 1 bad Pi, 2 bad Pa, 3 failure
|
|
|
|
|
enum {
|
|
|
|
|
WANT_CSI,
|
|
|
|
|
WANT_QMARK,
|
|
|
|
|
WANT_PI,
|
|
|
|
|
WANT_SEMI1,
|
|
|
|
|
WANT_SEMI2,
|
|
|
|
|
WANT_PV1,
|
|
|
|
|
WANT_PV2,
|
|
|
|
|
DONE,
|
|
|
|
|
} state = WANT_CSI;
|
|
|
|
|
int pv = 0;
|
|
|
|
|
int pi = 0;
|
|
|
|
|
while(read(fd, &in, 1) == 1){
|
|
|
|
|
//fprintf(stderr, "READ: %c 0x%02x\n", in, in);
|
|
|
|
|
if(in == 'c'){ // should match the end of DA
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
switch(state){
|
|
|
|
|
case WANT_CSI:
|
|
|
|
|
if(in == NCKEY_ESC){
|
|
|
|
|
state = WANT_QMARK;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_QMARK:
|
|
|
|
|
if(in == '?'){
|
|
|
|
|
state = WANT_PI;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_PI:
|
|
|
|
|
if(!isdigit(in)){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pi *= 10;
|
|
|
|
|
pi += in - '0';
|
|
|
|
|
if(pi >= 1 && pi <= 3){
|
|
|
|
|
state = WANT_SEMI1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_SEMI1:
|
|
|
|
|
if(in == ';'){
|
|
|
|
|
state = WANT_SEMI2;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_SEMI2:
|
|
|
|
|
if(in == ';'){
|
|
|
|
|
state = WANT_PV1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_PV1:
|
|
|
|
|
if(in == 'S'){
|
|
|
|
|
state = DONE;
|
|
|
|
|
}else if(val2 && in == ';'){
|
|
|
|
|
*val2 = 0;
|
|
|
|
|
state = WANT_PV2;
|
|
|
|
|
}else if(isdigit(in)){
|
|
|
|
|
pv *= 10;
|
|
|
|
|
pv += in - '0';
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_PV2:
|
|
|
|
|
if(in == 'S'){
|
|
|
|
|
state = DONE;
|
|
|
|
|
}else if(isdigit(in)){
|
|
|
|
|
*val2 *= 10;
|
|
|
|
|
*val2 += in - '0';
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case DONE:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(state == DONE){
|
|
|
|
|
if(pv >= 0 && (!val2 || *val2 >= 0)){
|
|
|
|
|
return pv;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
query_xtsmgraphics(int fd, const char* seq, int* val, int* val2){
|
|
|
|
|
if(blocking_write(fd, seq, strlen(seq))){
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int r = read_xtsmgraphics_reply(fd, val2);
|
|
|
|
|
if(r <= 0){
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
*val = r;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// query for Sixel support
|
|
|
|
|
static int
|
|
|
|
|
query_sixel(tinfo* ti, int fd){
|
|
|
|
|
if(blocking_write(fd, ESC_DA, strlen(ESC_DA))){
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
char in;
|
|
|
|
|
// perhaps the most lackadaisical response is that of st, which returns a
|
|
|
|
|
// bare ESC[?6c (note no semicolon). this is equivalent to alacritty's
|
|
|
|
|
// return, both suggesting a VT102. alacritty's miraculous technicolor VT102
|
|
|
|
|
// can display sixel, but real VT102s don't even reply to XTSMGRAPHICS, so we
|
|
|
|
|
// detect VT102 + TERM including alacritty, and special-case that.
|
|
|
|
|
// FIXME need unit tests on this
|
|
|
|
|
enum {
|
|
|
|
|
WANT_CSI,
|
|
|
|
|
WANT_QMARK,
|
|
|
|
|
WANT_SEMI,
|
|
|
|
|
WANT_C4, // want '4' to indicate sixel or 'c' to terminate
|
|
|
|
|
WANT_VT102_C,
|
|
|
|
|
DONE
|
|
|
|
|
} state = WANT_CSI;
|
|
|
|
|
bool in4 = false; // set true after seeing ";4", clear on semi
|
|
|
|
|
// we're looking for a 4 following a semicolon
|
|
|
|
|
while(state != DONE && read(fd, &in, 1) == 1){
|
|
|
|
|
switch(state){
|
|
|
|
|
case WANT_CSI:
|
|
|
|
|
if(in == NCKEY_ESC){
|
|
|
|
|
state = WANT_QMARK;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_QMARK:
|
|
|
|
|
if(in == '?'){
|
|
|
|
|
state = WANT_SEMI;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_SEMI:
|
|
|
|
|
if(in == ';'){
|
|
|
|
|
if(in4){
|
|
|
|
|
setup_sixel_bitmaps(ti);
|
|
|
|
|
}
|
|
|
|
|
state = WANT_C4;
|
|
|
|
|
}else if(in == 'c'){
|
|
|
|
|
if(in4){
|
|
|
|
|
setup_sixel_bitmaps(ti);
|
|
|
|
|
}
|
|
|
|
|
state = DONE;
|
|
|
|
|
}else if(in == '6'){
|
|
|
|
|
state = WANT_VT102_C;
|
|
|
|
|
}
|
|
|
|
|
in4 = false;
|
|
|
|
|
break;
|
|
|
|
|
case WANT_VT102_C:
|
|
|
|
|
if(in == 'c'){
|
|
|
|
|
if(ti->alacritty_sixel_hack){
|
|
|
|
|
setup_sixel_bitmaps(ti);
|
|
|
|
|
}
|
|
|
|
|
state = DONE;
|
|
|
|
|
}else if(in == ';'){
|
|
|
|
|
state = WANT_C4;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WANT_C4:
|
|
|
|
|
if(in == 'c'){
|
|
|
|
|
state = DONE;
|
|
|
|
|
}else if(in == '4'){
|
|
|
|
|
in4 = true;
|
|
|
|
|
state = WANT_SEMI;
|
|
|
|
|
}else{
|
|
|
|
|
in4 = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case DONE:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(ti->bitmap_supported){
|
|
|
|
|
if(ti->color_registers < 64){
|
|
|
|
|
ti->bitmap_supported = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|