-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathterminal.c
54 lines (46 loc) · 1.88 KB
/
terminal.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include "terminal.h"
static struct termios original_terminal_attributes;
void enter_raw_mode(){
// Keep track of original terminal settings so we can reset it when the program ends
tcgetattr(STDIN_FILENO, &original_terminal_attributes);
// Set to raw mode
struct termios raw_mode_attributes = original_terminal_attributes;
// ICANON: Read input byte rather than new line
// ISIG: Ignore Ctrl-c and Ctrl-z signals, which sends SIGINT and SIGTSTP
// IEXTEN: Ignore Ctrl-v
raw_mode_attributes.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN);
// ICRNL: Ignore Ctrl-s and Ctrl-q, which stops/start data transmission to this program from terminal
// Ctrl-m sends "carriage return" aka new line character. Do not want this behavior
raw_mode_attributes.c_iflag &= ~(ICRNL | IXON);
// Cooked move pressing enter will give \r\n to move cursor to right and down. We only want it to move down.
raw_mode_attributes.c_oflag &= ~(OPOST);
// minimum number of bytes of input needed before read() can return. 0 so we get every keystroke
raw_mode_attributes.c_cc[VMIN] = 0;
// Wait 1/10 second for user to type another character or else read() gives 0.
raw_mode_attributes.c_cc[VTIME] = 1;
// Apply attributes
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_mode_attributes);
// Go back to original terminal attributes when the program exists
atexit(disable_raw_mode);
}
void disable_raw_mode(){
tcsetattr(STDIN_FILENO, TCSAFLUSH, &original_terminal_attributes);
}
void clear_terminal(){
write(STDOUT_FILENO, "\x1b[2J", 4);
}
/**
*
* @param dimensions 0: Width 1: Height
*/
void get_terminal_dimensions(int dimensions[2]){
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
dimensions[0] = w.ws_col;
dimensions[1] = w.ws_row;
}