From 43258bfdff62ed038478a225122db5ca863e495d Mon Sep 17 00:00:00 2001 From: jxnshi Date: Thu, 2 Jan 2025 02:55:49 +0100 Subject: [PATCH] Working on profiles --- client-cli/client-cli | Bin 614304 -> 614312 bytes client-cli/command.odin | 2 +- client-cli/main.odin | 202 +++++++++++++++++++----------- client-cli/state.odin | 61 ++++++++-- ncurses/attributes.odin | 120 ++++++++++++++++++ ncurses/io.odin | 264 ++++++++++++++++++++++++++++++++++++++++ ncurses/ncurses.odin | 68 +++++++++++ ncurses/window.odin | 192 +++++++++++++++++++++++++++++ 8 files changed, 826 insertions(+), 83 deletions(-) create mode 100644 ncurses/attributes.odin create mode 100644 ncurses/io.odin create mode 100644 ncurses/ncurses.odin create mode 100644 ncurses/window.odin diff --git a/client-cli/client-cli b/client-cli/client-cli index 7fdf5e61620046cd7b0b42ca8fb8f01b886fa15b..47655fcbc5c844bf7325104921c626a50279e05d 100755 GIT binary patch delta 103725 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 U$$H1>_?OBpurhJDwZQ8Ae@&I4-2eap delta 103581 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%0D*0v;a?*i>U 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 diff --git a/client-cli/command.odin b/client-cli/command.odin index a9e076f..bd17fb0 100644 --- a/client-cli/command.odin +++ b/client-cli/command.odin @@ -11,7 +11,7 @@ handle_command :: proc(app: ^App, command: string) -> bool { // State specific commands. #partial switch app.state { - case .Ask_Config: + case .Invalid_Config: switch command { case ":r", ":retry": case ":del", ":delete": diff --git a/client-cli/main.odin b/client-cli/main.odin index 2602eb8..bd9fd59 100644 --- a/client-cli/main.odin +++ b/client-cli/main.odin @@ -1,15 +1,18 @@ package main +import "core:crypto/aes" import "core:crypto/ed25519" import "core:encoding/csv" import "core:encoding/json" import "core:fmt" import "core:log" +import "core:math/rand" import "core:net" import "core:os" import "core:strings" import "core:sync" import "core:thread" +import "core:time" import fpath "core:path/filepath" @@ -20,9 +23,12 @@ COLOR_SECOND :: 17 COLOR_THIRD :: 18 COLOR_FOURTH :: 19 -COLOR_FIRST :: 16 -COLOR_SECOND :: 17 -COLOR_THIRD :: 18 +json_marshal_options := json.Marshal_Options{ + spec = .JSON, + pretty = true, + use_spaces = true, + use_enum_names = true, +} Config :: struct { selected_profile: Maybe(string), @@ -34,33 +40,21 @@ config_deinit :: proc(config: Config) { } } -config_update :: proc(config: Config) { - home_path := os.get_env("HOME") - - storage_path := fpath.join({ home_path, "mesange" }, context.temp_allocator) - config_path := fpath.join({ storage_path, "config.json" }, context.temp_allocator) - +config_update :: proc(config: Config, app: App) { + config_path := fpath.join({ app.storage_path, "config.json" }, context.temp_allocator) config_file, err1 := os.open(config_path, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0777) if err1 != nil { - fmt.eprintln("Failed to open config file with error: .", err1) - os.exit(1) + app_set_info_bar(app, "Failed to save config.") + return } config_file_stream := os.stream_from_handle(config_file) - - marshal_options := json.Marshal_Options{ - spec = .JSON, - pretty = true, - use_spaces = true, - use_enum_names = true, - } - - err2 := json.marshal_to_writer(config_file_stream, config, &marshal_options) + err2 := json.marshal_to_writer(config_file_stream, config, &json_marshal_options) if err2 != nil { - fmt.eprintln("Failed to marshal config.") - os.exit(1) + app_set_info_bar(app, "Failed to save config.") + return } } @@ -68,6 +62,112 @@ Profile :: struct { private_key: ed25519.Private_Key, } +profile_load_from_name :: proc(name: string, app: App) -> (Profile, bool) { + buffer: [4096]u8 + profile_content: string + + // Loads encrypted. + if profile_password, ok := app.profile_password.?; ok { + encrypted_profile_path := fpath.join({ app.storage_path, selected_profile }, context.temp_allocator) + encrypted_profile_content, profile_read := os.read_entire_file_from_filename(encrypted_profile_path, context.temp_allocator) + + if !profile_read { + return {}, false + } + + ecb_context: aes.Context_ECB + aes.init_ecb(&ecb_context, app.profile_password.?) + + iv := encrypted_profile_content[:aes.GCM_IV_SIZE] + tag := encrypted_profile_content[len(iv):][:aes.GCM_TAG_SIZE] + ciphertext := encrypted_profile_content[len(iv) + len(tag):] + + if !aes.decrypt(&ecb_context, buffer[:], iv, {}, ciphertext, tag) { + app_set_info_bar(app, "Invalid password.") + app_set_state(app, .Ask_Profile_Password) + return + } + + profile_content = string(buffer[:len(ciphertext)]) + } + + // Loads clear text. + else { + profile_filename := strings.concatenate(app.config.selected_profile.?, ".json", context.temp_allocator) + profile_path = fpath.join({ app.storage_path, profile_filename }, context.temp_allocator) + + profile_content, profile_read := os.read_entire_file_from_filename(profile_path, context.temp_allocator) + + if !profile_read { + return {}, false + } + } +} + +profile_update :: proc(profile: Profile, app: App) { + profile_path: string + + if _, ok := app.profile_password.?; ok { + profile_path = fpath.join({ app.storage_path, app.config.selected_profile.? }, context.temp_allocator) + } else { + profile_filename := strings.concatenate(app.config.selected_profile.?, ".json", context.temp_allocator) + profile_path = fpath.join({ app.storage_path, profile_filename }, context.temp_allocator) + } + + profile_file, err1 := os.open(profile_path, os.O_WRONLY, | os.O_CREATE | os.O_TRUNC, 0777) + + if err1 != nil { + app_set_info_bar(app, "Failed to save profile.") + return + } + + // Saves encrypted. + if profile_password, ok := app.profile_password.?; ok { + json_string_builder: strings.Builder + strings.builder_init_none(&json_string_builder, context.temp_allocator) + + err2 := json.marshal_to_builder(&json_string_builder, profile, &json_marshal_options) + + if err2 != nil { + app_set_info_bar(app, "Failed to save profile.") + return + } + + json_string := strings.to_string(json_string_builder) + + aes_context: aes.Context_GCM + aes.init_gcm(&aes_context, profile_password) + + buffer: [4096]u8 + iv := buffer[:aes.GCM_IV_SIZE] + tag := buffer[len(iv):][:aes.GCM_TAG_SIZE] + + rand.read(iv[:]) + + aes.seal_gcm(&ecb_context, buffer[len(iv) + len(tag):], tag, iv, {}, transmute([]u8)json_string) + + content := string(buffer[:len(iv) + len(tag) + len(json_string)]) + + _, err3 := os.write_string(profile_file, content) + + if err3 != nil { + app_set_info_bar(app, "Failed to save profile.") + return + } + } + + // Saves clear text. + else { + profile_file_stream := os.stream_from_handle(profile_file) + err2 := json.marshal_to_writer(profile_file_stream, config, &json_marshal_options) + + if err2 != nil { + app_set_info_bar(app, "Failed to save profile.") + return + } + } +} + App :: struct { mutex: sync.Mutex, running: bool, @@ -79,7 +179,7 @@ App :: struct { box_message: Maybe(^nc.Window), info_bar: ^nc.Window, input_window: ^nc.Window, - + config: Config, profile_password: Maybe(string), profile: Profile, @@ -97,17 +197,11 @@ app_init :: proc() -> App { nc.init_color(COLOR_FIRST, 800, 800, 800) nc.init_color(COLOR_SECOND, 500, 500, 500) -<<<<<<< HEAD nc.init_color(COLOR_THIRD, 200, 200, 200) nc.init_color(COLOR_FOURTH, 000, 000, 000) nc.init_pair(1, COLOR_FIRST, COLOR_THIRD) nc.init_pair(2, COLOR_FIRST, COLOR_FOURTH) -======= - nc.init_color(COLOR_THIRD, 100, 100, 100) - - nc.init_pair(1, nc.COLOR_WHITE, COLOR_THIRD) ->>>>>>> refs/remotes/origin/master screen_height, screen_width := nc.getmaxyx(screen) @@ -129,11 +223,8 @@ app_init :: proc() -> App { } app := App{ -<<<<<<< HEAD running = true, -======= ->>>>>>> refs/remotes/origin/master screen = screen, storage_path = storage_path, @@ -141,11 +232,8 @@ app_init :: proc() -> App { input_window = input_window, } -<<<<<<< HEAD app_clear_info_bar(app) -======= app_set_state(&app, .Load_Config) ->>>>>>> refs/remotes/origin/master return app } @@ -167,17 +255,13 @@ app_set_state :: proc(app: ^App, state: State) { nc.clear() nc.refresh() -<<<<<<< HEAD -======= app_clear_box_message(app) ->>>>>>> refs/remotes/origin/master app_clear_info_bar(app^) app.state = state } app_set_info_bar :: proc(app: ^App, content: string) { -<<<<<<< HEAD app_clear_info_bar(app^) c_content := strings.clone_to_cstring(content, context.temp_allocator) @@ -187,15 +271,6 @@ app_set_info_bar :: proc(app: ^App, content: string) { nc.wattroff(app.info_bar, nc.COLOR_PAIR(1)) nc.wrefresh(app.info_bar) -======= - c_content := strings.clone_to_cstring(content, context.temp_allocator) - - color := nc.COLOR_PAIR(1) - - nc.wattron(app.info_bar, color) - nc.wprintw(app.info_bar, c_content) - nc.wattroff(app.info_bar, color) ->>>>>>> refs/remotes/origin/master } app_set_box_message :: proc(app: ^App, lines: []string) { @@ -220,15 +295,9 @@ app_set_box_message :: proc(app: ^App, lines: []string) { (screen_width - width) / 2, ) -<<<<<<< HEAD color := nc.COLOR_PAIR(2) nc.wattron(box_message, color) -======= - nc.refresh() - - nc.wattron(box_message, COLOR_FIRST) ->>>>>>> refs/remotes/origin/master for line, i in lines { c_line := strings.clone_to_cstring(line, context.temp_allocator) @@ -236,11 +305,7 @@ app_set_box_message :: proc(app: ^App, lines: []string) { } nc.box(box_message, 0, 0) -<<<<<<< HEAD nc.wattroff(box_message, color) -======= - nc.wattroff(box_message, COLOR_FIRST) ->>>>>>> refs/remotes/origin/master nc.wrefresh(box_message) @@ -251,7 +316,6 @@ app_set_box_message :: proc(app: ^App, lines: []string) { app_clear_info_bar :: proc(app: App) { height, width := nc.getmaxyx(app.info_bar) -<<<<<<< HEAD color := nc.COLOR_PAIR(1) nc.wclear(app.info_bar) @@ -262,20 +326,6 @@ app_clear_info_bar :: proc(app: App) { } nc.wattroff(app.info_bar, color) -======= - - color := nc.COLOR_PAIR(1) - - nc.wclear(app.info_bar) - - nc.wattron(app.info_bar, color) - - for _ in 0..>>>>>> refs/remotes/origin/master nc.wrefresh(app.info_bar) } @@ -312,7 +362,7 @@ handle_state :: proc(app: ^App) { for { switch app.state { case .Load_Config: state_load_config(app) - case .Ask_Config: state_ask_config(app) + case .Invalid_Config: state_invalid_config(app) case .Load_Profile: state_load_profile(app) case .Ask_Profile: state_ask_profile(app) @@ -323,6 +373,10 @@ handle_state :: proc(app: ^App) { } main :: proc() { + now := transmute(u64)time.now() + + context.random_generator := rand.create(now) + app := app_init() defer app_deinit(app) diff --git a/client-cli/state.odin b/client-cli/state.odin index 86ea699..eefad0e 100644 --- a/client-cli/state.odin +++ b/client-cli/state.odin @@ -1,5 +1,6 @@ package main +import "core:crypto/aes" import "core:encoding/json" import "core:fmt" import "core:os" @@ -9,7 +10,7 @@ import fpath "core:path/filepath" State :: enum { Load_Config, - Ask_Config, + Invalid_Config, Load_Profile, Ask_Profile, @@ -27,7 +28,7 @@ state_load_config :: proc(app: ^App) { err := json.unmarshal(raw_config, &config) if err != nil { - app_set_state(app, .Ask_Config) + app_set_state(app, .Invalid_Config) return } } else { @@ -39,7 +40,7 @@ state_load_config :: proc(app: ^App) { app_set_state(app, .Load_Profile) } -state_ask_config :: proc(app: ^App) { +state_invalid_config :: proc(app: ^App) { app_set_box_message( app, { @@ -78,13 +79,57 @@ state_load_profile :: proc(app: ^App) { return } - profile_content: string + profile, ok := profile_load_from_name(selected_profile, app) + + if !ok { + app_set_info_bar("Could not load profile, creating one.") + } + + load_profile: { + profile_content: string + + load_profile_content: { + load_encrypted: { + encrypted_profile_content, profile_read := os.read_entire_file_from_filename(encrypted_profile_path, context.temp_allocator) + + if !profile_read { + break load_encrypted + } + + ecb_context: aes.Context_ECB + aes.init_ecb(&ecb_context, app.profile_password.?) + + tag := encrypted_profile_content[:aes.GCM_TAG_SIZE] + + buffer: [4096]u8 + iv := encrypted_profile_content[:aes.GCM_IV_SIZE] + tag := encrypted_profile_content[len(iv):][:aes.GCM_TAG_SIZE] + ciphertext := encrypted_profile_content[len(iv) + len(tag):] + + if !aes.decrypt(&ecb_context, buffer[:], iv, {}, ciphertext, tag) { + app_set_info_bar(app, "Invalid password.") + app_set_state(app, .Ask_Profile_Password) + return + } + + profile_content = string(buffer[:len(ciphertext)]) + + break load_profile_content + } + + load_unencrypted: { + profile_filename := strings.concatenate(app.config.selected_profile.?, ".json", context.temp_allocator) + profile_path = fpath.join({ app.storage_path, profile_filename }, context.temp_allocator) + + profile_content, profile_read := os.read_entire_file_from_filename(profile_path, context.temp_allocator) + + if !profile_read { + break load_unencrypted + } + } - load_profile_content: { - encrypted_profile_content, profile_read := os.read_entire_file_from_filename(encrypted_profile_path) - if profile_read { - + break load_profile } } } diff --git a/ncurses/attributes.odin b/ncurses/attributes.odin new file mode 100644 index 0000000..9a04f5e --- /dev/null +++ b/ncurses/attributes.odin @@ -0,0 +1,120 @@ +package ncurses + +import "core:c" +foreign import ncurses "system:ncurses" + +@(private) +NCURSES_ATTR_SHIFT :: 8 + +@(private = "file") +ncurses_bits :: #force_inline proc(mask, shift: c.uint) -> c.int { + return c.int(mask << (shift + NCURSES_ATTR_SHIFT)) +} + +// -- Attributes + +A_NORMAL := c.int(c.uint(1) - c.uint(1)) +A_ATTRIBUTES := ncurses_bits(~(c.uint(1) - c.uint(1)), 0) +A_CHARTEXT := ncurses_bits(1, 0) - 1 +A_COLOR := ncurses_bits((c.uint(1) << 8) - c.uint(1), 0) +A_STANDOUT := ncurses_bits(1, 8) +A_UNDERLINE := ncurses_bits(1, 9) +A_REVERSE := ncurses_bits(1, 10) +A_BLINK := ncurses_bits(1, 11) +A_DIM := ncurses_bits(1, 12) +A_BOLD := ncurses_bits(1, 13) +A_ALTCHARSET := ncurses_bits(1, 14) +A_INVIS := ncurses_bits(1, 15) +A_PROTECT := ncurses_bits(1, 16) +A_HORIZONTAL := ncurses_bits(1, 17) +A_LEFT := ncurses_bits(1, 18) +A_LOW := ncurses_bits(1, 19) +A_RIGHT := ncurses_bits(1, 20) +A_TOP := ncurses_bits(1, 21) +A_VERTICAL := ncurses_bits(1, 22) +A_ITALIC := ncurses_bits(1, 23) /* ncurses extension */ + +// -- X/Open Attributes +// They're equivalent to the A_ attributes on ncurses + +WA_ATTRIBUTES := A_ATTRIBUTES +WA_NORMAL := A_NORMAL +WA_STANDOUT := A_STANDOUT +WA_UNDERLINE := A_UNDERLINE +WA_REVERSE := A_REVERSE +WA_BLINK := A_BLINK +WA_DIM := A_DIM +WA_BOLD := A_BOLD +WA_ALTCHARSET := A_ALTCHARSET +WA_INVIS := A_INVIS +WA_PROTECT := A_PROTECT +WA_HORIZONTAL := A_HORIZONTAL +WA_LEFT := A_LEFT +WA_LOW := A_LOW +WA_RIGHT := A_RIGHT +WA_TOP := A_TOP +WA_VERTICAL := A_VERTICAL +WA_ITALIC := A_ITALIC + +COLOR_BLACK :: 0 +COLOR_RED :: 1 +COLOR_GREEN :: 2 +COLOR_YELLOW :: 3 +COLOR_BLUE :: 4 +COLOR_MAGENTA :: 5 +COLOR_CYAN :: 6 +COLOR_WHITE :: 7 + +foreign ncurses { + // Maximum number of colors. + COLORS: c.int + // Maximum number of color-pairs. + COLORS_PAIRS: c.int + + attron :: proc(attr: c.int) -> c.int --- + attroff :: proc(attr: c.int) -> c.int --- + attrset :: proc(attr: c.int) -> c.int --- + wattron :: proc(win: ^Window, attr: c.int) -> c.int --- + wattroff :: proc(win: ^Window, attr: c.int) -> c.int --- + wattrset :: proc(win: ^Window, attr: c.int) -> c.int --- + + attr_on :: proc() --- // TODO + attr_off :: proc() --- // TODO + attr_set :: proc() --- // TODO + wattr_on :: proc() --- // TODO + wattr_off :: proc() --- // TODO + wattr_set :: proc() --- // TODO + + // changes the definition of a color. It takes four arguments: + // the number of the color to be changed followed by three RGB values (for the amounts of red, green, and blue components). + // + // The value of the first argument must be between 0 and COLORS. (See the section Colors for the default color index.) + // Each of the last three arguments must be a value between 0 and 1000. + // When init_color is used, all occurrences of that color on the screen immediately change to the new definition. + init_color :: proc(color, r, g, b: c.short) -> c.int --- + // Changes the definition of a color-pair. + // It takes three arguments: the number of the color-pair to be changed, the foreground color number, and the background color number. + // For portable applications: + // + // - The value of the first argument must be between 1 and COLOR_PAIRS-1, except that if default colors are used (see use_default_colors) + // the upper limit is adjusted to allow for extra pairs which use a default color in foreground and/or background. + // + // - The value of the second and third arguments must be between 0 and COLORS. Color pair 0 is assumed to be white on black, + // but is actually whatever the terminal implements before color is initialized. It cannot be modified by the application. + // If the color-pair was previously initialized, the screen is refreshed and all occurrences of that color-pair are changed to the new definition. + // + // As an extension, ncurses allows you to set color pair 0 via the assume_default_colors routine, + // or to specify the use of default colors (color number -1) if you first invoke the use_default_colors routine. + init_pair :: proc(pair_id, fg, bg: c.short) -> c.int --- + has_colors :: proc() -> c.bool --- + // Must be called if the programmer wants to use colors, and before any other color manipulation routine is called. + // It is good practice to call this routine right after initscr. + // + // start_color initializes eight basic colors (black, red, green, yellow, blue, magenta, cyan, and white), + // and two global variables, COLORS and COLOR_PAIRS (respectively defining the maximum number of colors and color-pairs the terminal can support). + // It also restores the colors on the terminal to the values they had when the terminal was just turned on. + start_color :: proc() -> c.int --- + use_default_colors :: proc() -> c.int --- + assume_default_colors :: proc(fg, bg: c.int) -> c.int --- + COLOR_PAIR :: proc(pair_id: c.int) -> c.int --- +} diff --git a/ncurses/io.odin b/ncurses/io.odin new file mode 100644 index 0000000..b50394a --- /dev/null +++ b/ncurses/io.odin @@ -0,0 +1,264 @@ +package ncurses + +import "core:c" +foreign import ncurses "system:ncurses" + +foreign ncurses { + + // Enables the terminal's keypad. + // If enabled, the user can press a function key (such as an arrow key) and wgetch returns a single value representing the function key, as in KEY_LEFT. + // + // If disabled, curses does not treat function keys specially and the program has to interpret the escape sequences itself. + // + // If the keypad in the terminal can be turned on (made to transmit) and off (made to work locally), turning on this option causes the terminal keypad to be turned on when wgetch is called. + // The default value for keypad is false. + keypad :: proc(win: ^Window, enable: bool) -> c.int --- + + // --- INPUT + + getch :: proc() -> c.int --- + wgetch :: proc(win: ^Window) -> c.int --- + mvgetch :: proc(y, x: c.int) -> c.int --- + mvwgetch :: proc(win: ^Window, y, x: c.int) -> c.int --- + + getstr :: proc(str: [^]byte) -> c.int --- + wgetstr :: proc(win: ^Window, str: [^]byte) -> c.int --- + getnstr :: proc(str: [^]byte, n: c.int) -> c.int --- + mvgetstr :: proc(y, x: c.int, str: [^]byte) -> c.int --- + mvwgetstr :: proc(win: ^Window, y, x: c.int, str: [^]byte) -> c.int --- + mvgetnstr :: proc(y, x: c.int, str: [^]byte, n: c.int) -> c.int --- + mvwgetnstr :: proc(win: ^Window, y, x: c.int, str: [^]byte, n: c.int) -> c.int --- + wgetnstr :: proc(win: ^Window, str: [^]byte, n: c.int) -> c.int --- + + ungetch :: proc(char: c.int) -> c.int --- + + scanw :: proc(fmt: cstring, #c_vararg args: ..any) -> c.int --- + wscanw :: proc(win: ^Window, fmt: cstring, #c_vararg args: ..any) -> c.int --- + mvscanw :: proc(y, x: c.int, fmt: cstring, #c_vararg args: ..any) -> c.int --- + mvwscanw :: proc(win: ^Window, y, x: c.int, fmt: cstring, #c_vararg args: ..any) -> c.int --- + + + // --- OUTPUT + + printw :: proc(fmt: cstring, #c_vararg args: ..any) -> c.int --- + wprintw :: proc(win: ^Window, fmt: cstring, #c_vararg args: ..any) -> c.int --- + mvprintw :: proc(y, x: c.int, fmt: cstring, #c_vararg args: ..any) -> c.int --- + mvwprintw :: proc(win: ^Window, y, x: c.int, fmt: cstring, #c_vararg args: ..any) -> c.int --- + + addch :: proc(char: c.uint) -> c.int --- + waddch :: proc(win: ^Window, char: c.uint) -> c.int --- + mvaddch :: proc(y, x: c.int, char: c.uint) -> c.int --- + mvwaddch :: proc(win: ^Window, y, x: c.int, char: c.uint) -> c.int --- + + addstr :: proc(str: cstring) -> c.int --- + waddstr :: proc(win: ^Window, str: cstring) -> c.int --- + mvaddstr :: proc(y, x: c.int, str: cstring) -> c.int --- + mvwaddstr :: proc(win: ^Window, y, x: c.int, str: cstring) -> c.int --- + + move :: proc(y, x: c.int) -> c.int --- + wmove :: proc(win: ^Window, y, x: c.int) --- + + // Returns a character string corresponding to the key c: + // + // - Printable characters are displayed as themselves, e.g., a one-character string containing the key. + // - Control characters are displayed in the ^X notation. + // - DEL (character 127) is displayed as ^?. + // - Values above 128 are either meta characters (if the screen has not been initialized, or if meta has been called with a TRUE parameter), shown in the M-X notation, or are displayed as themselves. In the latter case, the values may not be printable; this follows the X/Open specification. + // - Values above 256 may be the names of the names of function keys. + // - Otherwise (if there is no corresponding name) the function returns null, to denote an error. X/Open also lists an "UNKNOWN KEY" return value, which some implementations return rather than null. + keyname :: proc(c: c.int) -> cstring --- +} + +// down-arrow key +KEY_DOWN :: 0o402 +// up-arrow key +KEY_UP :: 0o403 +// left-arrow key +KEY_LEFT :: 0o404 +// right-arrow key +KEY_RIGHT :: 0o405 +// home key +KEY_HOME :: 0o406 +// backspace key +KEY_BACKSPACE :: 0o407 +// Function keys. Space for 64 +KEY_F0 :: 0o410 +KEY_F1 :: 0o411 +KEY_F2 :: 0o412 +KEY_F3 :: 0o413 +KEY_F4 :: 0o414 +KEY_F5 :: 0o415 +KEY_F6 :: 0o416 +KEY_F7 :: 0o417 +KEY_F8 :: 0o420 +KEY_F9 :: 0o421 +KEY_F10 :: 0o422 +KEY_F11 :: 0o423 +KEY_F12 :: 0o424 +KEY_F :: #force_inline proc(n: c.int) -> c.int { + return c.int(KEY_F0) + n +} +// delete-line key +KEY_DL :: 0o510 +// insert-line key +KEY_IL :: 0o511 +// delete-character key +KEY_DC :: 0o512 +// insert-character key +KEY_IC :: 0o513 +// sent by rmir or smir in insert mode +KEY_EIC :: 0o514 +// clear-screen or erase key +KEY_CLEAR :: 0o515 +// clear-to-end-of-screen key +KEY_EOS :: 0o516 +// clear-to-end-of-line key +KEY_EOL :: 0o517 +// scroll-forward key +KEY_SF :: 0o520 +// scroll-backward key +KEY_SR :: 0o521 +// next-page key +KEY_NPAGE :: 0o522 +// previous-page key +KEY_PPAGE :: 0o523 +// set-tab key +KEY_STAB :: 0o524 +// clear-tab key +KEY_CTAB :: 0o525 +// clear-all-tabs key +KEY_CATAB :: 0o526 +// enter/send key +KEY_ENTER :: 0o527 +// print key +KEY_PRINT :: 0o532 +// lower-left key (home down) +KEY_LL :: 0o533 +// upper left of keypad +KEY_A1 :: 0o534 +// upper right of keypad +KEY_A3 :: 0o535 +// center of keypad +KEY_B2 :: 0o536 +// lower left of keypad +KEY_C1 :: 0o537 +// lower right of keypad +KEY_C3 :: 0o540 +// back-tab key +KEY_BTAB :: 0o541 +// begin key +KEY_BEG :: 0o542 +// cancel key +KEY_CANCEL :: 0o543 +// close key +KEY_CLOSE :: 0o544 +// command key +KEY_COMMAND :: 0o545 +// copy key +KEY_COPY :: 0o546 +// create key +KEY_CREATE :: 0o547 +// end key +KEY_END :: 0o550 +// exit key +KEY_EXIT :: 0o551 +// find key +KEY_FIND :: 0o552 +// help key +KEY_HELP :: 0o553 +// mark key +KEY_MARK :: 0o554 +// message key +KEY_MESSAGE :: 0o555 +// move key +KEY_MOVE :: 0o556 +// next key +KEY_NEXT :: 0o557 +// open key +KEY_OPEN :: 0o560 +// options key +KEY_OPTIONS :: 0o561 +// previous key +KEY_PREVIOUS :: 0o562 +// redo key +KEY_REDO :: 0o563 +// reference key +KEY_REFERENCE :: 0o564 +// refresh key +KEY_REFRESH :: 0o565 +// replace key +KEY_REPLACE :: 0o566 +// restart key +KEY_RESTART :: 0o567 +// resume key +KEY_RESUME :: 0o570 +// save key +KEY_SAVE :: 0o571 +// shifted begin key +KEY_SBEG :: 0o572 +// shifted cancel key +KEY_SCANCEL :: 0o573 +// shifted command key +KEY_SCOMMAND :: 0o574 +// shifted copy key +KEY_SCOPY :: 0o575 +// shifted create key +KEY_SCREATE :: 0o576 +// shifted delete-character key +KEY_SDC :: 0o577 +// shifted delete-line key +KEY_SDL :: 0o600 +// select key +KEY_SELECT :: 0o601 +// shifted end key +KEY_SEND :: 0o602 +// shifted clear-to-end-of-line key +KEY_SEOL :: 0o603 +// shifted exit key +KEY_SEXIT :: 0o604 +// shifted find key +KEY_SFIND :: 0o605 +// shifted help key +KEY_SHELP :: 0o606 +// shifted home key +KEY_SHOME :: 0o607 +// shifted insert-character key +KEY_SIC :: 0o610 +// shifted left-arrow key +KEY_SLEFT :: 0o611 +// shifted message key +KEY_SMESSAGE :: 0o612 +// shifted move key +KEY_SMOVE :: 0o613 +// shifted next key +KEY_SNEXT :: 0o614 +// shifted options key +KEY_SOPTIONS :: 0o615 +// shifted previous key +KEY_SPREVIOUS :: 0o616 +// shifted print key +KEY_SPRINT :: 0o617 +// shifted redo key +KEY_SREDO :: 0o620 +// shifted replace key +KEY_SREPLACE :: 0o621 +// shifted right-arrow key +KEY_SRIGHT :: 0o622 +// shifted resume key +KEY_SRESUME :: 0o623 +// shifted save key +KEY_SSAVE :: 0o624 +// shifted suspend key +KEY_SSUSPEND :: 0o625 +// shifted undo key +KEY_SUNDO :: 0o626 +// suspend key +KEY_SUSPEND :: 0o627 +// undo key +KEY_UNDO :: 0o630 +// Mouse event has occurred +KEY_MOUSE :: 0o631 +// Terminal resize event +KEY_RESIZE :: 0o632 +// Maximum key value is 0632 +KEY_MAX :: 0o777 diff --git a/ncurses/ncurses.odin b/ncurses/ncurses.odin new file mode 100644 index 0000000..4125108 --- /dev/null +++ b/ncurses/ncurses.odin @@ -0,0 +1,68 @@ +package ncurses + +import "core:c" + +foreign import ncurses "system:ncurses" + +OK: c.int : 0 +ERR: c.int : -1 + +foreign ncurses { + // Usually the first routine called when initializing a program. + // + // It determines the terminal type and initializes all ncurses data structures. + // It internally calls the first refresh(). + // + // Error: writes a message to stderr and exit + // Success: returns stdscr + initscr :: proc() -> ^Window --- + + // Use halfdelay mode. + // + // Similar to cbreak(), however after tenths of seconds + // have passed an ERR is returned if nothing was typed. + halfdelay :: proc(tenths: c.int) -> c.int --- + + // Copies the stdscr to the physical terminal screen. + refresh :: proc() -> c.int --- + // Copies the specified window to the physical terminal screen. + wrefresh :: proc(win: ^Window) -> c.int --- + + // All allocated resources from ncurses are cleaned up and the tty modes are restored to the status they had before calling initscr(). + endwin :: proc() -> c.int --- + + // Place the terminal into raw mode. + // + // Raw mode is similar to cbreak mode, in that characters typed are immediately passed through to the user program. + // The differences are that in raw mode, the interrupt, quit, suspend, and flow control characters are all passed through uninterpreted, instead of generating a signal. + // The behavior of the BREAK key depends on other bits in the tty driver that are not set by curses. + raw :: proc() -> c.int --- + // Place the terminal out of raw mode. + // + // Raw mode is similar to cbreak mode, in that characters typed are immediately passed through to the user program. + // The differences are that in raw mode, the interrupt, quit, suspend, and flow control characters are all passed through uninterpreted, instead of generating a signal. + // The behavior of the BREAK key depends on other bits in the tty driver that are not set by curses. + noraw :: proc() -> c.int --- + + // Disables line buffering and erase/kill character-processing (interrupt and flow control characters are unaffected), + // making characters typed by the user immediately available to the program. + cbreak :: proc() -> c.int --- + // Returns the terminal to normal (cooked) mode. + nocbreak :: proc() -> c.int --- + + // Show typed characters when user when using getch. + echo :: proc() -> c.int --- + // Hide typed characters when user when using getch. + noecho :: proc() -> c.int --- + + // Set the cursor's visibility. + // + // Visibility modes: + // 0: invisible + // 1: normal + // 2: very visible + // + // Success: Returns previous cursor state + // Error: Returns ERR + curs_set :: proc(visibility: c.int) -> c.int --- +} diff --git a/ncurses/window.odin b/ncurses/window.odin new file mode 100644 index 0000000..287fcab --- /dev/null +++ b/ncurses/window.odin @@ -0,0 +1,192 @@ +package ncurses + +import "core:c" +foreign import ncurses "system:ncurses" + +@(private = "file") +_win_st :: struct {} + +Window :: distinct _win_st + +@(private) +foreign ncurses { + acs_map: [^]c.uint + + getattrs :: proc(win: ^Window) -> c.int --- + getcurx :: proc(win: ^Window) -> c.int --- + getcury :: proc(win: ^Window) -> c.int --- + getbegx :: proc(win: ^Window) -> c.int --- + getbegy :: proc(win: ^Window) -> c.int --- + getmaxx :: proc(win: ^Window) -> c.int --- + getmaxy :: proc(win: ^Window) -> c.int --- + getparx :: proc(win: ^Window) -> c.int --- + getpary :: proc(win: ^Window) -> c.int --- +} + +foreign ncurses { + stdscr: ^Window + LINES: c.int + COLS: c.int + + // The upper left-hand corner of the window is at line y, column x. + // If either h or w is zero, they default to LINES - y and COLS - x. + // + // A new full-screen window is created by calling newwin(0, 0, 0, 0). + newwin :: proc(h, w, y, x: c.int) -> ^Window --- + // Deletes the named window, freeing all memory associated with it (it does not actually erase the window's screen image). + // + // Subwindows must be deleted before the main window can be deleted. + // + // Returns an error if the window pointer is null, or if the window is the parent of another window. + delwin :: proc(win: ^Window) -> c.int --- + + // moves the window so that the upper left-hand corner is at position (x, y). + // If the move would cause the window to be off the screen, it is an error and the window is not moved. + // Moving subwindows is allowed, but should be avoided. + mvwin :: proc(win: ^Window, y, x: c.int) --- + + // Draw a box around the edges of a window. + // + // verch: vertical character + // horch: horizontal character + box :: proc(win: ^Window, verch, horch: c.int) --- + // Draw a box around the edges of stdscr. + // + // ls: left side, + // rs: right side, + // ts: top side, + // bs: bottom side, + // tl: top left-hand corner, + // tr: top right-hand corner, + // bl: bottom left-hand corner, and + // br: bottom right-hand corner. + // + // If any of these arguments is zero, then the corresponding default values are used instead: + // ACS_VLINE, + // ACS_VLINE, + // ACS_HLINE, + // ACS_HLINE, + // ACS_ULCORNER, + // ACS_URCORNER, + // ACS_LLCORNER, + // ACS_LRCORNER. + border :: proc(ls, rs, ts, bs, tl, tr, bl, br: c.uint) --- + // Draw a box around the edges of a window. + // + // ls: left side, + // rs: right side, + // ts: top side, + // bs: bottom side, + // tl: top left-hand corner, + // tr: top right-hand corner, + // bl: bottom left-hand corner, and + // br: bottom right-hand corner. + // + // If any of these arguments is zero, then the corresponding default values are used instead: + // ACS_VLINE, + // ACS_VLINE, + // ACS_HLINE, + // ACS_HLINE, + // ACS_ULCORNER, + // ACS_URCORNER, + // ACS_LLCORNER, + // ACS_LRCORNER. + wborder :: proc(win: ^Window, ls, rs, ts, bs, tl, tr, bl, br: c.uint) --- + + // The clear and wclear routines are like erase and werase, but they also call clearok, + // so that the screen is cleared completely on the next call to wrefresh for that window and repainted from scratch. + clear :: proc() -> c.int --- + // The clear and wclear routines are like erase and werase, but they also call clearok, + // so that the screen is cleared completely on the next call to wrefresh for that window and repainted from scratch. + wclear :: proc(win: ^Window) -> c.int --- + + // Erase from the cursor to the end of screen. + clrtoeol :: proc() -> c.int --- + // Erase from the cursor to the end of screen. + wclrtoeol :: proc(win: ^Window) -> c.int --- + + // Copy blanks to every position in stdscr, clearing the screen. + erase :: proc() -> c.int --- + // Copy blanks to every position in the window, clearing the screen. + werase :: proc(win: ^Window) -> c.int --- + + // Resize the window. If either dimension is larger than the current values, the window's data is filled with blanks that have the current background rendition (as set by wbkgndset) merged into them. + wresize :: proc(win: ^Window, h, w: c.int) -> c.int --- +} + +// Get the current coordinates of the cursor. +getyx :: proc(win: ^Window) -> (y, x: c.int) {return getcury(win), getcurx(win)} +// Get absolute screen coordinates of the specified window. +getbegyx :: proc(win: ^Window) -> (y, x: c.int) {return getbegy(win), getbegx(win)} +// Get the size of the current window. +getmaxyx :: proc(win: ^Window) -> (y, x: c.int) {return getmaxy(win), getmaxx(win)} +// Get the beginning coordinates of the subwindow relative to the parent window. +getparyx :: proc(win: ^Window) -> (y, x: c.int) {return getpary(win), getparx(win)} + +// -- VT100 symbols begin here + +// upper left corner +ACS_ULCORNER := acs_map['l'] +// lower left corner +ACS_LLCORNER := acs_map['m'] +// upper right corner +ACS_URCORNER := acs_map['k'] +// lower right corner +ACS_LRCORNER := acs_map['j'] +// tee pointing right +ACS_LTEE := acs_map['t'] +// tee pointing left +ACS_RTEE := acs_map['u'] +// tee pointing up +ACS_BTEE := acs_map['v'] +// tee pointing down +ACS_TTEE := acs_map['w'] +// horizontal line +ACS_HLINE := acs_map['q'] +// vertical line +ACS_VLINE := acs_map['x'] +// large plus or crossover +ACS_PLUS := acs_map['n'] +// scan line 1 +ACS_S1 := acs_map['o'] +// scan line 9 +ACS_S9 := acs_map['s'] +// diamon] +ACS_DIAMOND := acs_map['`'] +// checker board (stipple) +ACS_CKBOARD := acs_map['a'] +// degree symbol +ACS_DEGREE := acs_map['f'] +// plus/minus +ACS_PLMINUS := acs_map['g'] +// bulle] +ACS_BULLET := acs_map['~'] + +// -- Teletype 5410v1 symbols begin here + +ACS_LARROW := acs_map[','] /* arro] pointing left */ +ACS_RARROW := acs_map['+'] /* arro] pointing right */ +ACS_DARROW := acs_map['.'] /* arro] pointing down */ +ACS_UARROW := acs_map['-'] /* arrow pointing up */ +ACS_BOARD := acs_map['h'] /* board of squares */ +ACS_LANTERN := acs_map['i'] /* lantern symbol */ +ACS_BLOCK := acs_map['0'] /* solid square block */ + +// -- These aren't documented, but a lot of System Vs have them anyway +// -- (you can spot pprryyzz{{||}} in a lot of AT&T terminfo strings). +// -- The ACS_names may not match AT&T's, our source didn't know them. + +// scan line 3 +ACS_S3 := acs_map['p'] +// scan line 7 +ACS_S7 := acs_map['r'] +// less/equal +ACS_LEQUAL := acs_map['y'] +// greater/equal +ACS_GEQUAL := acs_map['z'] +// Pi +ACS_PI := acs_map['{'] +// not equal +ACS_NEQUAL := acs_map['|'] +// UK pound sign +ACS_STERLING := acs_map['}'] -- 2.49.0