aboutsummaryrefslogtreecommitdiff
path: root/TUI/windows.jai
blob: ef0cfa841b81d807fddafba8f4db8574bf79e1b7 (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
#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;
}