diff options
author | Haoran S. Diao (刁浩然) <0@hairydiode.xyz> | 2025-09-06 02:07:20 -0700 |
---|---|---|
committer | Haoran S. Diao (刁浩然) <0@hairydiode.xyz> | 2025-09-06 02:07:20 -0700 |
commit | 43e028136ef84c900f565946d5f694f9e4fc4eee (patch) | |
tree | 45b0991fc19d10ad5ba35c1d816ff92d4076d7aa | |
parent | 33c523fdef955c60fb81ccf3e30b8eace12933c9 (diff) |
Fully functional so far. Just need to clean up the code and actually import the
input method table
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | im.h | 116 | ||||
-rw-r--r-- | imtable.h | 3 | ||||
-rw-r--r-- | ptyim.c | 71 |
4 files changed, 140 insertions, 55 deletions
@@ -18,6 +18,11 @@ SIGWINCH hook, very simple fg/bg ctrl-c ctrl-z all works cmus, bcmus, all work +vitetris +telnet star wars + +pageup/down doesn't work when im is on +vim starts in vreplace mode for some reason -------------------------------=[Useful Commands]=------------------------------ ps l @@ -1,7 +1,17 @@ #include "imtable.h" #define IM_BUFFER_LEN 32 -char im_buffer[IM_BUFFER_LEN]; +#define ENTER_KEY 0x0D +#define BACKSPACE_KEY 0x7F +//#define BACKSPACE_KEY '+' +//setting it to the actual escape character interferes with arrow keys and +//whatnot +//#define ESCAPE_KEY 0x1B +#define ESCAPE_KEY '`' +//Vertical Tab Ctrl+K +#define TOGGLE_KEY 0x0B +char im_buffer[IM_BUFFER_LEN+1]; char im_buffer_pos = 0; +int im_on = 1; //recursive search, returns -1 on failure //searches from [start, end) int im_search(char * input, int start, int end) { @@ -11,7 +21,7 @@ int im_search(char * input, int start, int end) { } //test for middle, works even for 1 width middle=start int middle = start + (end-start)/2; - printf("testing:%s\n",im_table[middle][0]); + //printf("testing:%s\n",im_table[middle][0]); int test = strncmp(im_table[middle][0], input, IM_TABLE_ENTRY_LEN); if (test == 0) { return middle; @@ -37,57 +47,75 @@ int im_search(char * input, int start, int end) { } //returns output len, since we want to be able to handle null bytes as well int update_im_state(char input, char * output) { - if ( ('a' <= input <= 'z')||('0' <= input <= '9')||(input == ' ') ) { - if (im_buffer_pos < IM_BUFFER_LEN) { + if (input == TOGGLE_KEY) { + im_on = !im_on; + //clears the im buffer if its toggling off + if (!im_on) { + im_buffer[0] = 0; + im_buffer_pos = 0; + } + } + //just exit if the im is off + if (!im_on) { + output[0] = input; + output[1] = 0; + return 1; + } + if ( ('a' <= input && input <= 'z')||('0' <= input && input <= '9')||(input == ' ') ) { + if ( (im_buffer_pos < IM_BUFFER_LEN) && (im_buffer_pos < IM_TABLE_ENTRY_LEN) ){ im_buffer[im_buffer_pos] = input; im_buffer_pos++; + im_buffer[im_buffer_pos] = 0; } else { //passthrough output[0] = input; output[1] = 0; return 1; } - } - int im_entry = im_search(im_buffer,0, IM_TABLE_LEN); - if (im_entry != -1) { - strncpy(output, im_table[im_entry][1], IM_TABLE_ENTRY_LEN); - im_buffer[0] = 0; - im_buffer_pos = 0; - return strlen(im_table[im_entry][1]); - } - //these only do something if there's something in the buffer, otherwise - //passthrough - if (im_buffer_pos > 0) { - switch (input) { - //escape, cancels - case 0x1B: - im_buffer[0] = 0; - im_buffer_pos = 0; - return 0; - break; - //enter, enters the buffer - case 0x0A: - for (int i = 0; i <im_buffer_pos; i++) { - output[i] = im_buffer[i]; - } - output[im_buffer_pos] = 0; - int tmp = im_buffer_pos; - im_buffer_pos = 0; - return tmp; - break; - //backspace - case 0x08: - if (im_buffer_pos > 0) { - im_buffer_pos--; - im_buffer[im_buffer_pos] = 0; - } - return 0; - break; + //if there's a match return it + int im_entry = im_search(im_buffer, 0, IM_TABLE_LEN); + if (im_entry != -1) { + //clear the buffer + im_buffer[0] = 0; + im_buffer_pos = 0; + strncpy(output, im_table[im_entry][1], IM_TABLE_ENTRY_LEN); + return strlen(im_table[im_entry][1]); + } + } else { + //these only do something if there's something in the buffer, otherwise + //passthrough + if (im_buffer_pos > 0) { + switch (input) { + //escape, cancels + case ESCAPE_KEY: + im_buffer[0] = 0; + im_buffer_pos = 0; + return 0; + break; + //enter, enters the buffer + case ENTER_KEY: + for (int i = 0; i <im_buffer_pos; i++) { + output[i] = im_buffer[i]; + } + output[im_buffer_pos] = 0; + int tmp = im_buffer_pos; + im_buffer_pos = 0; + return tmp; + break; + //backspace + case BACKSPACE_KEY: + if (im_buffer_pos > 0) { + im_buffer_pos--; + im_buffer[im_buffer_pos] = 0; + } + return 0; + break; + } } + //default behavior of passthrough + output[0] = input; + output[1] = 0; + return 1; } - //default behavior of passthrough - output[0] = input; - output[1] = 0; - return 1; } @@ -1,4 +1,4 @@ -#define IM_TABLE_LEN 4 +#define IM_TABLE_LEN 5 #define IM_TABLE_ENTRY_LEN 8 //assumes this is sorted char im_table[][3][IM_TABLE_ENTRY_LEN] = { @@ -6,4 +6,5 @@ char im_table[][3][IM_TABLE_ENTRY_LEN] = { {"aa ", "對", "100"}, {"b ", "八", "100"}, {"ba ", "不", "100"}, + {"1", "一", "100"}, }; @@ -18,18 +18,64 @@ void childhook(int a) { running = 0; } int pty_slave = -1; +//terminal rows and cols +int trows = 0; +int tcols = 0; //hook for SIGWINCH void winchhook(int a) { struct winsize sz; ioctl(STDIN_FILENO, TIOCGWINSZ, &sz); + trows = sz.ws_row; + tcols = sz.ws_col; + //trick programs into thinking the terminal is smaller than it is + if (sz.ws_row >= 1) { + sz.ws_row--; + } ioctl(pty_slave, TIOCSWINSZ, &sz); } +void disp_im() { + //3 spaces for the im indicator +1 for automargin + int im_col = tcols - IM_TABLE_ENTRY_LEN - 4; + char pos_str[32] = ""; + int l = sprintf(pos_str, "\033[%d;%df",trows, im_col); + //printf("\0337"); + //printf("\033[%d;%df",trows,im_col); + //printf("\033[0;0f",trows,im_col); + //printf("\033[7m"); + //if (im_on) { + // printf("漢"); + //} else { + // printf("英"); + //} + //printf("%s",im_buffer); + //printf("\033[0m"); + //printf("\0338"); + write(STDOUT_FILENO,"\0337",2); + //also writes to top left the current im buffer + //write(STDOUT_FILENO,"\033[33;14f",8); + //write(STDOUT_FILENO,"\033[0;4f",6); + //write to the bottom left corner + write(STDOUT_FILENO, pos_str,l); + //invert video + write(STDOUT_FILENO,"\033[7m",4); + //overwrite what was there previously + write(STDOUT_FILENO," ", + IM_TABLE_ENTRY_LEN+4); + write(STDOUT_FILENO, pos_str,l); + //im mode indicator + if (im_on) { + write(STDOUT_FILENO,"漢:",4); + } else { + write(STDOUT_FILENO,"英:",4); + } + //actual buffer + write(STDOUT_FILENO,im_buffer,im_buffer_pos); + //restore cursor pos and attrbutes + write(STDOUT_FILENO,"\033[0m",4); + write(STDOUT_FILENO,"\0338",2); +} int main (int argc, char * argv[], char * envp[]) { - printf("%s: %d\n", "a", im_search("a",0,IM_TABLE_LEN)); - printf("%s: %d\n", "bb", im_search("bb",0,IM_TABLE_LEN)); - printf("%s: %d\n", "c", im_search("c",0,IM_TABLE_LEN)); - printf("%s: %d\n", "ba", im_search("ba",0,IM_TABLE_LEN)); //creates the pty master int pty_master = posix_openpt(O_RDWR); if (pty_master < 0) { @@ -55,7 +101,6 @@ int main (int argc, char * argv[], char * envp[]) { } //gets slave path char * pty_slave_fn = ptsname(pty_master); - printf("Slave name %s\n", pty_slave_fn); //tries to open pty slave pty_slave = open(pty_slave_fn, O_RDWR); if (pty_slave < 0) { @@ -69,7 +114,6 @@ int main (int argc, char * argv[], char * envp[]) { winchhook(0); //forks for running bash pid_t mypid = fork(); - printf("forked w/ pid %d\n", mypid); if (mypid == 0) { //set self to be session leader @@ -129,14 +173,21 @@ int main (int argc, char * argv[], char * envp[]) { //read uses file descriptors and is a system call chars_read = read(pty_master,readbuffer,1); if (chars_read >0) { - write(STDIN_FILENO,readbuffer,1); + write(STDOUT_FILENO,readbuffer,1); } - //relays input from stdin - char input_buffer[IM_TABLE_ENTRY_LEN] = {0}; chars_read = read(STDIN_FILENO, readbuffer, 1); if (chars_read > 0) { - write(pty_master,readbuffer,1); + //write(pty_master,readbuffer,1); + //relays input from stdin + char input_buffer[IM_TABLE_ENTRY_LEN] = {0}; + int im_chars = update_im_state(readbuffer[0], + input_buffer); + input_buffer[im_chars] = 0; + if (im_chars >0) { + write(pty_master,input_buffer,im_chars); + } + disp_im(); } } } |