diff options
author | Haoran S. Diao (刁浩然) <0@hairydiode.xyz> | 2025-09-13 02:16:22 -0700 |
---|---|---|
committer | Haoran S. Diao (刁浩然) <0@hairydiode.xyz> | 2025-09-13 02:16:22 -0700 |
commit | 619d74d6ad638de0dceb9d5d3cc1a6b3f0ed3963 (patch) | |
tree | a7f00e32ca6ad6fac52e362fe929a02c0de6ccbb | |
parent | dbc69eaff9a6bb80cfe324252f76dbb94781538b (diff) |
made the escape state machien also keep track of cursor save/restore parity and
clear screen sequences, have the im_disp_routine only update when these are
equal and a clear screen sequence has been sent
-rw-r--r-- | escape.h | 67 | ||||
-rw-r--r-- | ptyim.c | 26 |
2 files changed, 69 insertions, 24 deletions
@@ -12,6 +12,16 @@ //nF ESC[0x20-02F]*[0x30-0x7E] //Fp ESC[0x30-0x3F] save and clear + +//Clearing commands +//ESC c +//ESC [ [1-3] J + +//ESC [ [1-2] K +//ESC [ m @ +// note: these two can't clear im preview b/c of scroll locking + + //last read key enum esc_state { //C0 except BEL or ESC, \n ,\r and \f @@ -59,14 +69,22 @@ int safe_state(enum esc_state state) { enum esc_state in_state = NORMAL; //global pty -> stdout ESC state enum esc_state out_state = NORMAL; +//global output parity +int out_c_parity = 0; +//global output clear state, cleared by im_routine_update +int out_clr = 0; -//c0 c1 c2 osc, sf nF sequences +//updates the state, the return is the type of the last character read -//also ESC 7 and ESC 8 up down bit -//have a semaphore and above lock, IM will draw if available when input updates -//or if some time has passed since output has been written +//updates c parity depending on cursor store and restore + //if c parity is not NULL +//sets clr to 1 if it encounters a cursor clear escape sequence + // if clr is not NULL -enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_state state) { +enum esc_state update_esc_state(char * buff,unsigned int buff_len, + enum esc_state state, + int * c_parity, int * clr) +{ for (int i = 0; i < buff_len; i++) { char c = buff[i]; switch (state) { @@ -92,8 +110,13 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat } break; case ESC: + if (c == 'c') { + if (clr != NULL) { + *clr = 1; + } + } //fix length C1 - if (c == 'N' || c == 'O') { + else if (c == 'N' || c == 'O') { state = C1; } else if (c == '[') { @@ -103,18 +126,32 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat else if (c == ']' || c =='P' || c == '^' || c == 'X' || c == '_') { state = C1_START; } - //nF - else if (c >= 0x20 && c <= 0x2F) { - state = nF_START; - } else if (c == '\\') { state - ST; } else if (c == '7') { state = DECSC; + if ( c_parity != NULL) { + *c_parity++; + } } else if (c == '8') { - state = DECSC; + state = DECRC; + if ( c_parity != NULL) { + *c_parity--; + } + } + //nF + else if (c >= 0x20 && c <= 0x2F) { + state = nF_START; + } + //all other Fe/C1 Sequences, should be fixed len + else if (c >= 0x40 && c <= 0x5F) { + state = C1; + } + //Fs Sequences + else if (c >= 0x60 && c <= 0x7E) { + state = C1; } else if (c == 0x1B) { state = DOUBLE_ESC; @@ -134,7 +171,12 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat break; case CSI_START: case CSI_MID: - if (c >= 0x30 && c <= 0x3F) { + if (c == 'J') { + state = CSI_END; + if (clr != NULL) { + *clr = 1; + } + } else if (c >= 0x30 && c <= 0x3F) { state = CSI_MID; } else if (c >= 0x20 && c <= 0x2F) { state = CSI_MID; @@ -159,3 +201,4 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat } return state; } + @@ -49,8 +49,6 @@ pthread_t om_thread; pthread_t im_disp_thread; //stdout semaphore sem_t out_sem; -//tracks whether the screen has been updated by om -int om_updated = 1; //return 0 on success, -1 on error @@ -111,29 +109,33 @@ void * om_routine( void *arg) { // pty_master -> STDOUT int wchars_read = read(pty_master,write_buffer, WRITE_BUFFER_LEN); if (wchars_read >0) { - out_state = update_esc_state(write_buffer, wchars_read, out_state); - fprintf(stderr, "%c: %d\n", write_buffer[wchars_read-1], out_state); sem_wait(&out_sem); + out_state = update_esc_state(write_buffer, wchars_read, out_state, + &out_c_parity, &out_clr); + fprintf(stderr, "%c: %d\n", write_buffer[wchars_read-1], out_state); write(STDOUT_FILENO,write_buffer,wchars_read); sem_post(&out_sem); - //sets update flag, im_disp_routine will set it to 0 - om_updated = 1; } } } void * im_disp_routine (void *args) { while (running) { // Every run of this loop, it checks to see if im_buffer has - // updated, if it has, and no escape sequences have been written - // so far, it will display the im - if (im_updated |om_updated) { - fprintf(stderr, "printing im statusline\n"); + // updated, or if the screen has been cleared + + //then checks if the cursor save parity is right, and if the + //last output tot the terminal is safe to append to + if (im_updated | out_clr) { + if (out_c_parity != 0) { + continue; + } if (safe_state(out_state)) { + fprintf(stderr, "printing im statusline\n"); sem_wait(&out_sem); disp_im(STDIN_FILENO, trows, tcols); sem_post(&out_sem); im_updated = 0; - om_updated = 0; + out_clr = 0; } } } @@ -235,7 +237,7 @@ int main (int argc, char * argv[], char * envp[]) { if (rchars_read > 0) { //feeds input char into the escape state //machine - in_state = update_esc_state(read_buffer, 1, in_state); + in_state = update_esc_state(read_buffer, 1, in_state, NULL, NULL); //skips if the char was anything but //normal if (in_state == NORMAL || in_state ==DOUBLE_ESC) { |