|
|
@ -623,19 +623,24 @@ typedef struct init_state {
|
|
|
|
STATE_XTGETTCAP3, // XTGETTCAP, got 'r' (DCS 0/1 + r Pt ST)
|
|
|
|
STATE_XTGETTCAP3, // XTGETTCAP, got 'r' (DCS 0/1 + r Pt ST)
|
|
|
|
STATE_TDA, // tertiary DA
|
|
|
|
STATE_TDA, // tertiary DA
|
|
|
|
STATE_SDA, // secondary DA (CSI > Pp ; Pv ; Pc c)
|
|
|
|
STATE_SDA, // secondary DA (CSI > Pp ; Pv ; Pc c)
|
|
|
|
STATE_DA, // primary DA (CSI ? ... c)
|
|
|
|
STATE_DA, // primary DA (CSI ? ... c) OR XTSMGRAPHICS
|
|
|
|
|
|
|
|
STATE_DA_1, // got '1', could be XTSMGRAPHICS color registers or primary DA
|
|
|
|
|
|
|
|
STATE_DA_6, // got '6', could be VT102 or VT220/VT320/VT420
|
|
|
|
|
|
|
|
STATE_DA_DRAIN, // drain out the primary DA to 'c'
|
|
|
|
|
|
|
|
STATE_SIXEL,// XTSMGRAPHICS about Sixel geometry (got '2')
|
|
|
|
} state;
|
|
|
|
} state;
|
|
|
|
bool xtgettcap_good; // high when we've received DCS 1
|
|
|
|
bool xtgettcap_good; // high when we've received DCS 1
|
|
|
|
} init_state;
|
|
|
|
} init_state;
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME ought implement the full Williams automaton
|
|
|
|
// FIXME ought implement the full Williams automaton
|
|
|
|
|
|
|
|
// FIXME doesn't handle 8-bit controls (would need convert UTF-8)
|
|
|
|
// returns 1 after handling the Device Attributes response, 0 if more input
|
|
|
|
// returns 1 after handling the Device Attributes response, 0 if more input
|
|
|
|
// ought be fed to the machine, and -1 on an invalid state transition.
|
|
|
|
// ought be fed to the machine, and -1 on an invalid state transition.
|
|
|
|
static int
|
|
|
|
static int
|
|
|
|
pump_control_read(init_state* inits, unsigned char c){
|
|
|
|
pump_control_read(init_state* inits, unsigned char c){
|
|
|
|
fprintf(stderr, "state: %2d char: %1c %3d %02x\n", inits->state, isprint(c) ? c : ' ', c, c);
|
|
|
|
fprintf(stderr, "state: %2d char: %1c %3d %02x\n", inits->state, isprint(c) ? c : ' ', c, c);
|
|
|
|
if(c == NCKEY_ESC){
|
|
|
|
if(c == NCKEY_ESC){
|
|
|
|
if(inits->state != STATE_NULL){
|
|
|
|
if(inits->state != STATE_NULL && inits->state != STATE_XTGETTCAP3){
|
|
|
|
fprintf(stderr, "Unexpected escape in state %d\n", inits->state);
|
|
|
|
fprintf(stderr, "Unexpected escape in state %d\n", inits->state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
inits->state = STATE_ESC;
|
|
|
|
inits->state = STATE_ESC;
|
|
|
@ -650,6 +655,10 @@ pump_control_read(init_state* inits, unsigned char c){
|
|
|
|
inits->state = STATE_CSI;
|
|
|
|
inits->state = STATE_CSI;
|
|
|
|
}else if(c == 'P'){
|
|
|
|
}else if(c == 'P'){
|
|
|
|
inits->state = STATE_DCS;
|
|
|
|
inits->state = STATE_DCS;
|
|
|
|
|
|
|
|
}else if(c == '\\'){
|
|
|
|
|
|
|
|
fprintf(stderr, "string terminator -- parse previous response FIXME\n");
|
|
|
|
|
|
|
|
// FIXME only now do we parse e.g. XTGETTCAP response
|
|
|
|
|
|
|
|
inits->state = STATE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case STATE_CSI: // terminated by 0x40--0x7E ('@'--'~')
|
|
|
|
case STATE_CSI: // terminated by 0x40--0x7E ('@'--'~')
|
|
|
@ -688,12 +697,7 @@ pump_control_read(init_state* inits, unsigned char c){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case STATE_XTGETTCAP3:
|
|
|
|
case STATE_XTGETTCAP3:
|
|
|
|
if(c == '\\'){
|
|
|
|
|
|
|
|
// FIXME done, go parse if good
|
|
|
|
|
|
|
|
inits->state = STATE_NULL;
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
// FIXME feed to terminfo buffer
|
|
|
|
// FIXME feed to terminfo buffer
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case STATE_TDA:
|
|
|
|
case STATE_TDA:
|
|
|
|
// FIXME
|
|
|
|
// FIXME
|
|
|
@ -703,8 +707,28 @@ pump_control_read(init_state* inits, unsigned char c){
|
|
|
|
inits->state = STATE_NULL;
|
|
|
|
inits->state = STATE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// primary device attributes and XTSMGRAPHICS replies are generally
|
|
|
|
|
|
|
|
// indistinguishable until well into the escape. one can get:
|
|
|
|
|
|
|
|
// XTSMGRAPHICS: CSI ? Pi ; Ps ; Pv S {Pi: 123} {Ps: 0123}
|
|
|
|
|
|
|
|
// DA: CSI ? 1 ; 2 c ("VT100 with Advanced Video Option")
|
|
|
|
|
|
|
|
// CSI ? 1 ; 0 c ("VT101 with No Options")
|
|
|
|
|
|
|
|
// CSI ? 4 ; 6 c ("VT132 with Advanced Video and Graphics")
|
|
|
|
|
|
|
|
// CSI ? 6 c ("VT102")
|
|
|
|
|
|
|
|
// CSI ? 7 c ("VT131")
|
|
|
|
|
|
|
|
// CSI ? 1 2 ; Ps c ("VT125")
|
|
|
|
|
|
|
|
// CSI ? 6 2 ; Ps c ("VT220")
|
|
|
|
|
|
|
|
// CSI ? 6 3 ; Ps c ("VT320")
|
|
|
|
|
|
|
|
// CSI ? 6 4 ; Ps c ("VT420")
|
|
|
|
case STATE_DA: // return success on end of DA
|
|
|
|
case STATE_DA: // return success on end of DA
|
|
|
|
if(c == 'c'){
|
|
|
|
if(c == '1'){
|
|
|
|
|
|
|
|
inits->state = STATE_DA_1;
|
|
|
|
|
|
|
|
}else if(c == '2'){
|
|
|
|
|
|
|
|
inits->state = STATE_SIXEL;
|
|
|
|
|
|
|
|
}else if(c == '4' || c == '7'){ // VT132, VT131
|
|
|
|
|
|
|
|
inits->state = STATE_DA_DRAIN;
|
|
|
|
|
|
|
|
}else if(c == '6'){
|
|
|
|
|
|
|
|
inits->state = STATE_DA_6;
|
|
|
|
|
|
|
|
}else if(c == 'c'){
|
|
|
|
inits->state = STATE_NULL;
|
|
|
|
inits->state = STATE_NULL;
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -731,17 +755,20 @@ control_read(tinfo* tcache, int ttyfd){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while((s = read(ttyfd, buf, sizeof(buf))) != -1){
|
|
|
|
while((s = read(ttyfd, buf, sizeof(buf))) != -1){
|
|
|
|
for(ssize_t idx = 0; idx < s ; ++idx){
|
|
|
|
for(ssize_t idx = 0; idx < s ; ++idx){
|
|
|
|
if(pump_control_read(&inits, buf[idx]) == 1){ // success!
|
|
|
|
int r = pump_control_read(&inits, buf[idx]);
|
|
|
|
|
|
|
|
if(r == 1){ // success!
|
|
|
|
free(buf);
|
|
|
|
free(buf);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}else if(r < 0){
|
|
|
|
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err:
|
|
|
|
fprintf(stderr, "failed on %d (%s)\n", ttyfd, strerror(errno));
|
|
|
|
fprintf(stderr, "failed on %d (%s)\n", ttyfd, strerror(errno));
|
|
|
|
free(buf);
|
|
|
|
free(buf);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// FIXME complete terminal detection
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ncinputlayer_init(tinfo* tcache, FILE* infp){
|
|
|
|
int ncinputlayer_init(tinfo* tcache, FILE* infp){
|
|
|
|
ncinputlayer* nilayer = &tcache->input;
|
|
|
|
ncinputlayer* nilayer = &tcache->input;
|
|
|
@ -756,6 +783,9 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp){
|
|
|
|
nilayer->inputbuf_valid_starts = 0;
|
|
|
|
nilayer->inputbuf_valid_starts = 0;
|
|
|
|
nilayer->inputbuf_write_at = 0;
|
|
|
|
nilayer->inputbuf_write_at = 0;
|
|
|
|
nilayer->input_events = 0;
|
|
|
|
nilayer->input_events = 0;
|
|
|
|
control_read(tcache, nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd);
|
|
|
|
if(control_read(tcache, nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd)){
|
|
|
|
|
|
|
|
input_free_esctrie(&nilayer->inputescapes);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|