diff options
Diffstat (limited to 'kscurses/init.jai')
| -rw-r--r-- | kscurses/init.jai | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/kscurses/init.jai b/kscurses/init.jai new file mode 100644 index 0000000..b67c52f --- /dev/null +++ b/kscurses/init.jai @@ -0,0 +1,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); +} |
