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
|
#import "Basic";
Drawings :: struct {
CornerBR :: "\x6A";
CornerTR :: "\x6B";
CornerTL :: "\x6C";
CornerBL :: "\x6D";
Cross :: "\x6E";
LineH :: "\x71";
TeeL :: "\x74";
TeeR :: "\x75";
TeeB :: "\x76";
TeeT :: "\x77";
LineV :: "\x78";
}
Commands :: struct {
EnterAlternateBuffer :: "\e[?1049h";
EnterMainBuffer :: "\e[?1049l";
EnterDrawingMode :: "\e(0";
EnterNormalMode :: "\e(B";
ClearScreen :: "\e[2J";
// Cursor Visibility
ShowCursor :: "\e[?25h";
HideCursor :: "\e[?25l";
StartBlinking :: "\e[?25h]";
StopBlinking :: "\e[?25l]";
// Cursor Shape
DefaultShape :: "\e[0 q";
BlinkingBlockShape :: "\e[1 q";
SteadyBlockShape :: "\e[2 q";
BlinkingUnderlineShape :: "\e[3 q";
SteadyUnderlineShape :: "\e[4 q";
BlinkingBarShape :: "\e[5 q";
SteadyBarShape :: "\e[6 q";
// Input Mode
KeypadAppMode :: "\e=";
KeypadNumMode :: "\e>";
CursorAppMode :: "\e[?1h";
CursorNormalMode :: "\e[?1l";
// Query State
QueryCursorPos :: "\e[6n"; // Emits the cursor position as: ESC [ <r> ; <c> R Where <r> = row and <c> = column.
QueryDeviceAttributes :: "\e[0c";
}
start :: () {
write_string(Commands.EnterAlternateBuffer);
}
stop :: () {
write_string(Commands.EnterMainBuffer);
}
draw_box :: (x: int, y: int, width: int, height: int, to_standard_error := false) {
write_string(Commands.HideCursor);
write_strings(
// Commands.EnterNormalMode,
Commands.EnterDrawingMode,
"\e[1;1H", // Move to position 1,1
// TODO // Move pointer to top-left corner.
Drawings.CornerTL,
to_standard_error = to_standard_error);
for 1..width-2 {
write_string(Drawings.LineH, to_standard_error = to_standard_error);
}
write_string(Drawings.CornerTR, to_standard_error = to_standard_error);
// TODO Take care of the temporary allocations.
for idx: 2..height-1 {
tmpL := tprint("\e[%;%H", idx, 1);
tmpR := tprint("\e[%;%H", idx, width);
write_strings(
tmpL,
Drawings.LineV,
tmpR,
Drawings.LineV,
to_standard_error = to_standard_error);
}
tmpBL := tprint("\e[%;%H", height, 1);
write_strings(
tmpBL,
Drawings.CornerBL,
to_standard_error = to_standard_error);
for 1..width-2 {
write_string(Drawings.LineH, to_standard_error = to_standard_error);
}
write_string(Drawings.CornerBR, to_standard_error = to_standard_error);
write_strings(
// TODO // print
Commands.EnterNormalMode,
to_standard_error = to_standard_error);
}
clear_screen :: inline () {
write_string(Commands.ClearScreen);
}
|