summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README5
-rw-r--r--im.h116
-rw-r--r--imtable.h3
-rw-r--r--ptyim.c71
4 files changed, 140 insertions, 55 deletions
diff --git a/README b/README
index d5eb34e..f6923a5 100644
--- a/README
+++ b/README
@@ -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
diff --git a/im.h b/im.h
index 4980938..e038f77 100644
--- a/im.h
+++ b/im.h
@@ -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;
}
diff --git a/imtable.h b/imtable.h
index dc51809..66c7f78 100644
--- a/imtable.h
+++ b/imtable.h
@@ -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"},
};
diff --git a/ptyim.c b/ptyim.c
index 047bb25..6fa6ac1 100644
--- a/ptyim.c
+++ b/ptyim.c
@@ -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();
}
}
}