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
|
#import "Windows";
kernel32 :: #system_library "kernel32";
GetConsoleScreenBufferInfo :: (hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) -> bool #foreign kernel32;
ReadConsoleA :: (hConsoleHandle: HANDLE, buff : *u8, chars_to_read : s32, chars_read : *s32, lpInputControl := *void ) -> bool #foreign kernel32;
// ReadConsole :: (hConsoleInput: HANDLE, lpBuffer: *u8, nNumberOfCharsToRead: s32, lpNumberOfCharsRead: *s32, pInputControl := *void) -> bool #foreign kernel32;
GetConsoleMode :: (hConsoleHandle: HANDLE, lpMode: *u32) -> bool #foreign kernel32;
SetConsoleMode :: (hConsoleHandle: HANDLE, dwMode: u32) -> bool #foreign kernel32;
GetLastError :: () -> s32 #foreign kernel32;
ENABLE_VIRTUAL_TERMINAL_INPUT :: 0x0200;
ENABLE_PROCESSED_OUTPUT :: 0x0001;
ENABLE_WRAP_AT_EOL_OUTPUT :: 0x0002;
ENABLE_VIRTUAL_TERMINAL_PROCESSING :: 0x0004;
DISABLE_NEWLINE_AUTO_RETURN :: 0x0008;
ENABLE_LVB_GRID_WORLDWIDE :: 0x0010;
SHORT :: s16;
WORD :: u16;
DWORD :: s32;
COORD :: struct {
X : SHORT;
Y : SHORT;
}
SMALL_RECT :: struct {
Left : SHORT;
Top : SHORT;
Right : SHORT;
Bottom : SHORT;
}
CONSOLE_SCREEN_BUFFER_INFO :: struct {
dwSize : COORD;
dwCursorPosition : COORD;
wAttributes : WORD;
srWindow : SMALL_RECT;
dwMaximumWindowSize : COORD;
}
stdin: HANDLE;
initial_stdin_mode: u32;
stdout: HANDLE;
initial_stdout_mode: u32;
OS_prepare_terminal :: () {
print("TODO TUI\n", to_standard_error = true);
// stdin
stdin = GetStdHandle(STD_INPUT_HANDLE );
if stdin == INVALID_HANDLE_VALUE {
print("Invalid input handler.", to_standard_error = true);
return;
}
if GetConsoleMode(stdin, *initial_stdin_mode) == false {
print("Failed to get input mode.", to_standard_error = true);
return;
}
if SetConsoleMode(stdin, initial_stdin_mode | ENABLE_VIRTUAL_TERMINAL_INPUT) == false {
print("Failed to set input mode: %.", GetLastError(), to_standard_error = true);
return;
}
// stdout
stdout = GetStdHandle(STD_OUTPUT_HANDLE);
outMode: u32 = 0;
if stdout == INVALID_HANDLE_VALUE {
print("Invalid output handler.", to_standard_error = true);
return;
}
if GetConsoleMode(stdout, *initial_stdout_mode) == false {
print("Failed to get output mode.", to_standard_error = true);
return;
}
if SetConsoleMode(stdout, initial_stdout_mode | ENABLE_PROCESSED_OUTPUT| ENABLE_VIRTUAL_TERMINAL_PROCESSING) == false {
print("Failed to set output mode: %.", GetLastError(), to_standard_error = true);
return;
}
}
OS_reset_terminal :: () {
print("TODO TUI\n", to_standard_error = true);
if SetConsoleMode(stdin, initial_stdin_mode) == false {
print("Failed to reset input mode: %.", GetLastError(), to_standard_error = true);
return;
}
if SetConsoleMode(stdout, initial_stdout_mode) == false {
print("Failed to reset output mode: %.", GetLastError(), to_standard_error = true);
return;
}
}
OS_get_terminal_size :: () -> rows: int, columns: int {
ScreenBufferInfo: CONSOLE_SCREEN_BUFFER_INFO;
GetConsoleScreenBufferInfo(stdout, *ScreenBufferInfo);
columns := ScreenBufferInfo.srWindow.Right - ScreenBufferInfo.srWindow.Left + 1;
rows := ScreenBufferInfo.srWindow.Bottom - ScreenBufferInfo.srWindow.Top + 1;
return rows, columns;
}
|