term.c (1674B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <termios.h> 4 #include <unistd.h> 5 #include <sys/ioctl.h> 6 7 #include "vip.h" 8 9 extern editor vip; 10 11 void die(const char *s) 12 { 13 write(STDOUT_FILENO, "\x1b[2J", 4); 14 write(STDOUT_FILENO, "\x1b[H", 3); 15 perror(s); 16 exit(1); 17 } 18 19 void reset_term() 20 { 21 if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &vip.termios) == -1) { 22 die("tcsetattr"); 23 } 24 } 25 26 /* 27 * Setup terminal 28 */ 29 void setup_term() 30 { 31 if (tcgetattr(STDIN_FILENO, &vip.termios) == -1) { 32 die("tcgetattr"); 33 } 34 atexit(reset_term); 35 36 struct termios raw = vip.termios; 37 /* disbable echo, line output and signals */ 38 raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); 39 raw.c_oflag &= ~(OPOST); 40 raw.c_cflag |= (CS8); 41 raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); 42 raw.c_cc[VMIN] = 0; 43 raw.c_cc[VTIME] = 1; 44 if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) { 45 die("tcsetattr"); 46 } 47 } 48 49 int get_cursor_position(int *rows, int *cols) 50 { 51 char buf[32]; 52 unsigned int i = 0; 53 if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) { 54 return -1; 55 } 56 while (i < sizeof(buf) - 1) { 57 if (read(STDIN_FILENO, &buf[i], 1) != 1) { 58 break; 59 } 60 if (buf[i] == 'R') { 61 break; 62 } 63 i++; 64 } 65 buf[i] = '\0'; 66 if (buf[0] != '\x1b' || buf[1] != '[') { 67 return -1; 68 } 69 if (sscanf(&buf[2], "%d;%d", rows, cols) != 2) { 70 return -1; 71 } 72 return 0; 73 } 74 75 int get_window_size(int *rows, int *cols) 76 { 77 struct winsize ws; 78 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { 79 /* Can't get window size */ 80 if (write(STDOUT_FILENO, "\x1b[999C\x1b[999B", 12) != 12) { 81 return -1; 82 } 83 return get_cursor_position(rows, cols); 84 } else { 85 *cols = ws.ws_col; 86 *rows = ws.ws_row; 87 return 0; 88 } 89 }