linux textui programming
setup terminal input and output
int ttyfd = open("/dev/tty", O_RDWR);struct termios termattr;// get terminal attr from ttytcgetattr(ttyfd, &termattr);// set terminal to "raw" modecfmakeraw(&termattr);// turn off input buffertermattr.c_cc[VMIN] = 1;termattr.c_cc[VTIME] = 0;// apply terminal attr to ttytcsetattr(ttyfd, TCSAFLUSH, &termattr);
move cursor
you can use termcap to control terminal:
// from: busybox editors/vi.c// VT102 ESC sequences.// See "Xterm Control Sequences"// http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#define ESC "\033"// Cursor to given coordinate (1,1: top left)#define ESC_SET_CURSOR_POS ESC"[%u;%uH"int textui_setcur(int ttyfd, unsigned int col, unsigned int row){char buf[32];snprintf(buf, 32, ESC_SET_CURSOR_POS, row, col);return write(ttyfd, buf, strlen(buf));}
move cursor to 2, 5:
textui_setcur(ttyfd,2,5);
clear screen
// from: busybox editors/vi.c// Clear-to-end-of-screen.// (We use default param here.// Full sequence is "ESC [ <num> J",// <num> is 0/1/2 = "erase below/above/all".)#define ESC_CLEAR2EOS ESC"[J"int textui_clearterm(int ttyfd){int ret;ret = textui_setcur(ttyfd, 1, 1);if (ret < 0)return ret;char buf[32];snprintf(buf, 32, ESC_CLEAR2EOS);return write(ttyfd, buf, strlen(buf));}
make screen blank:
textui_clearterm(ttyfd);
draw a string
it will draw “Hello World” on 4, 5
char *msg = "Hello World";textui_setcur(ttyfd,4,5);write(ttyfd,msg,strlen(msg));
erase a string
erase a string is also simple:
it will clean “Hello World” on 4, 5 (just fill space)
msg = " ";textui_setcur(ttyfd,4,5);write(ttyfd,msg,strlen(msg));
get a char from input
after setup terminal, getchar() is like getch();
int c;while (1) {c = getchar();textui_setcur(ttyfd,4,5);write(ttyfd,&c,1);if (c == 'q')break;}
get terminal size
struct winsize wsz;ioctl(ttyfd, TIOCGWINSZ, &wsz);printf("COL: %d, ROW: %d\n", wsz.ws_col, wsz.ws_row);