summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--escape.h67
-rw-r--r--ptyim.c26
2 files changed, 69 insertions, 24 deletions
diff --git a/escape.h b/escape.h
index 103139a..20ec740 100644
--- a/escape.h
+++ b/escape.h
@@ -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;
}
+
diff --git a/ptyim.c b/ptyim.c
index 5ff0eee..3ac78d0 100644
--- a/ptyim.c
+++ b/ptyim.c
@@ -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) {