build up pump_control_read() state machine, terminate on DA response #1469

pull/1764/head
nick black 3 years ago committed by Nick Black
parent a35ea97e2c
commit fc6bc1a3d8

@ -610,6 +610,86 @@ void ncinputlayer_stop(ncinputlayer* nilayer){
input_free_esctrie(&nilayer->inputescapes);
}
typedef struct init_state {
tinfo* tcache;
enum {
STATE_NULL,
STATE_ESC,
STATE_CSI,
STATE_DCS,
STATE_DA,
} state;
} init_state;
// FIXME ought implement the full Williams automaton
// 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.
static int
pump_control_read(init_state* inits, unsigned char c){
fprintf(stderr, "char: %c %d %02x\n", c, c, c);
if(c == NCKEY_ESC){
if(inits->state != STATE_NULL){
fprintf(stderr, "Unexpected escape in state %d\n", inits->state);
}
inits->state = STATE_ESC;
return 0;
}
switch(inits->state){
case STATE_NULL:
// not an escape -- throw into user queue
break;
case STATE_ESC:
if(c == '['){
inits->state = STATE_CSI;
}else if(c == 'P'){
inits->state = STATE_DCS;
}
break;
case STATE_CSI:
if(c == '?'){
inits->state = STATE_DA;
}
break;
case STATE_DA:
if(c == 'c'){
inits->state = STATE_NULL;
return 1;
}
break;
default:
fprintf(stderr, "Reached invalid init state %d\n", inits->state);
return -1;
}
return 0;
}
// complete the terminal detection process
static int
control_read(tinfo* tcache, int ttyfd){
init_state inits = {
.tcache = tcache,
.state = STATE_NULL,
};
unsigned char* buf;
ssize_t s;
if((buf = malloc(BUFSIZ)) == NULL){
return -1;
}
while((s = read(ttyfd, buf, sizeof(buf))) != -1){
for(ssize_t idx = 0; idx < s ; ++idx){
if(pump_control_read(&inits, buf[idx]) == 1){ // success!
free(buf);
return 0;
}
}
}
fprintf(stderr, "failed on %d (%s)\n", ttyfd, strerror(errno));
free(buf);
return -1;
}
// FIXME complete terminal detection
int ncinputlayer_init(tinfo* tcache, FILE* infp){
ncinputlayer* nilayer = &tcache->input;
setbuffer(infp, NULL, 0);
@ -623,8 +703,6 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp){
nilayer->inputbuf_valid_starts = 0;
nilayer->inputbuf_write_at = 0;
nilayer->input_events = 0;
if(nilayer->ttyfd >= 0){
// FIXME complete terminal detection
}
control_read(tcache, nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd);
return 0;
}

Loading…
Cancel
Save