aboutsummaryrefslogtreecommitdiff
path: root/kscurses/init.jai
blob: b67c52fb85f17e4773a2f4efb64d0ec9c3c6f666 (plain)
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
terminal_state : struct {
	size : ivec2;
	cursor := ivec2.{-1, -1}; // {-1, -1} if cursor hidden
	last_mode : Graphics_Mode;
}
update_terminal_size :: () {
	TIOCGWINSZ :: 0x5413;
	winsize : struct {
		ws_row, ws_col, ws_xpixel, ws_ypixel : u16;
	}
	ioctl(0, TIOCGWINSZ, *winsize);
	terminal_state.size = .{xx winsize.ws_col, xx winsize.ws_row};
}

ks_init :: () {
	#if OS == .LINUX {
		__old_logger = context.logger;
		context.logger = file_logger;

		ks_write("\e[?25l");	// hide cursor
		ks_write("\e7");		// save cursor position
		ks_write("\e[?1047h");	// switch screen
		ks_write("\e[?30l");	// hide scrollbar

		ks_write("\e[H"); 		// move to top left corner
		ks_write("\e[0m");		// set default mode
		ks_write("\e[2J"); 		// clear screen
		{
			tcgetattr(STDIN_FILENO, *__term);
			term_new := __term;

			term_new.c_iflag &= 0xFFFFFA14;// ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
			term_new.c_oflag &= 0xFFFFFFFE;// ~OPOST;
			term_new.c_lflag &= 0xFFFF7FB4;// ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
			term_new.c_cflag &= 0xFFFFFECF;// ~(CSIZE | PARENB);
			term_new.c_cflag |= 0x00000030;

			tcsetattr(STDIN_FILENO, 0, *term_new);	
		}
		update_terminal_size();		
	} else {
		assert(false, "procedure call on unsupported OS\n");
	}
}
ks_terminate :: () {
	#if OS == .LINUX {
		tcsetattr(STDIN_FILENO, 0, *__term); // return echo

		ks_write("\e[?47l");	// restore screen
		ks_write("\e8");		// restore cursor
		ks_write("\e[?25h");	// show cursor
		ks_write("\e[?30h");	// show scrollbar
		terminal_state = .{};

		context.logger = __old_logger;		
	} else {
		assert(false, "procedure call on unsupported OS\n");
	}
}
use_ks_curses :: () #expand {
	ks_init();
	`defer {
		ks_terminate();
	}
}
use_default_winch_handler :: () #expand {
	init_default_winch_handler();
	`defer deinit_default_winch_handler();
}
init_default_winch_handler :: () {
	#if OS == .LINUX {
		act := sigaction_t.{
			sa_handler = (sig : s32) #c_call {
				new_context: Context;
				push_context new_context {
					update_terminal_size();
				}
			},
			sa_mask = sigset_t.{__val[0] = SIGWINCH}
		};
		sigaction(SIGWINCH, *act, null);		
	} else {
		assert(false, "procedure call on unsupported OS\n");		
	}
}
deinit_default_winch_handler :: () {
	#if OS == .LINUX {
		sa : sigaction_t;
		sa.sa_handler = SIG_DFL;
		sigaction(SIGWINCH, null, *sa);
	} else {

	}
}

#scope_file
__old_logger : type_of(context.logger);

#if OS == .LINUX {
	__term : My_Termios;

	My_Termios :: struct {
		c_iflag : u32;
		c_oflag : u32;
		c_cflag : u32;
		c_lflag : u32;
		unknown_pad : u8;
		c_cc : [32]u8;
		c_ispeed : u32;
		c_ospeed : u32;
	}

	libc :: #system_library "libc";
	tcsetattr :: (fd : s32, optional_actions : s32, termios_p : *My_Termios) -> s32 #foreign libc;
	tcgetattr :: (fd : s32, termios_p : *My_Termios) -> s32 #foreign libc;	
}

#import "File";
file_logger :: (message: string, data: *void, info: Log_Info) {
	file, ok := file_open("log.txt",for_writing=true, keep_existing_content=true);
	if !ok return;

	file_write(*file, tprint("[%] %", calendar_to_string(to_calendar(current_time_consensus())), message));
	file_close(*file);	
}