From 91195d34e1f71246cadc41705004d66ab647087e Mon Sep 17 00:00:00 2001 From: cflip Date: Sun, 8 Jan 2023 14:15:01 -0700 Subject: Initial import of existing source code This is based off of snaptoken's "Build Your Own Text Editor" tutorial at https://viewsourcecode.org/snaptoken/kilo/. --- terminal.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 terminal.c (limited to 'terminal.c') diff --git a/terminal.c b/terminal.c new file mode 100644 index 0000000..c24f46d --- /dev/null +++ b/terminal.c @@ -0,0 +1,84 @@ +#include "terminal.h" + +#include +#include +#include +#include +#include + +static struct termios original_termios; + +void die(const char* message) +{ + /* Clear the screen */ + write(STDOUT_FILENO, "\x1b[2J", 4); + write(STDOUT_FILENO, "\x1b[H", 3); + + perror(message); + exit(1); +} + +void disable_raw_mode() +{ + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &original_termios) == -1) + die("tcsetattr"); +} + +/* Disables any input and output processing from the terminal */ +void enable_raw_mode() +{ + if (tcgetattr(STDIN_FILENO, &original_termios) == -1) + die("tcgetattr"); + + atexit(disable_raw_mode); + + struct termios raw = original_termios; + raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + raw.c_oflag &= ~(OPOST); + raw.c_cflag |= (CS8); + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + + raw.c_cc[VMIN] = 0; + raw.c_cc[VTIME] = 1; + + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) + die("tcsetattr"); +} + +int get_cursor_position(int* rows, int* cols) +{ + char buffer[32]; + unsigned int i = 0; + + if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) + return -1; + + while (i < sizeof(buffer) - 1) { + if (read(STDIN_FILENO, &buffer[i], 1) != 1) break; + if (buffer[i] == 'R') break; + i++; + } + buffer[i] = '\0'; + + printf("\r\n&buffer[1]: '%s'\r\n", &buffer[1]); + + if (buffer[0] != '\x1b' || buffer[1] != '[') return -1; + if (sscanf(&buffer[2], "%d;%d", rows, cols) != 2) return -1; + + return 0; +} + +int get_window_size(int* rows, int* cols) +{ + struct winsize size; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) == -1 || size.ws_col == 0) { + if (write(STDOUT_FILENO, "\x1b[999C\x1b[999B", 12) != 12) + return -1; + return get_cursor_position(rows, cols); + } else { + *cols = size.ws_col; + *rows = size.ws_row; + return 0; + } +} -- cgit v1.2.3