diff --git a/xurses.c b/xurses.c index 914fbc4..06b79f3 100644 --- a/xurses.c +++ b/xurses.c @@ -19,7 +19,9 @@ int curses_screen_height = 0; int curses_screen_size = 0; char * curses_screen = NULL; -void (* curses_action ['~' - ' ']) (void) = { 0 }; +char curses_format [CURSES_LENGTH + 1] = "\033[-;3-m-\033[0m"; + +void (* curses_action ['~' - ' ' + 1]) (void) = { 0 }; struct termios curses_old_terminal; struct termios curses_new_terminal; @@ -29,12 +31,12 @@ void curses_initialize (void) { struct winsize screen_dimension; - fatal_failure (ioctl (STDOUT_FILENO, TIOCGWINSZ, & screen_dimension) == -1, "[!] ioctl: Failed to get terminal size."); + fatal_failure (ioctl (STDOUT_FILENO, TIOCGWINSZ, & screen_dimension) == -1, "ioctl: Failed to get terminal dimensions."); curses_screen_width = (int) screen_dimension.ws_col; curses_screen_height = (int) screen_dimension.ws_row; - fatal_failure (tcgetattr (STDIN_FILENO, & curses_old_terminal) == -1, "[!] tcgetattr: Failed to get terminal attributes."); + fatal_failure (tcgetattr (STDIN_FILENO, & curses_old_terminal) == -1, "tcgetattr: Failed to get default terminal attributes."); curses_new_terminal = curses_old_terminal; @@ -46,9 +48,9 @@ void curses_initialize (void) { curses_new_terminal.c_cflag |= (unsigned int) (CS8); curses_new_terminal.c_lflag &= (unsigned int) ~(ECHO | ICANON | IEXTEN | ISIG); - fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_new_terminal) == -1, "[!] tcsetattr: Failed to set raw terminal attributes."); + fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_new_terminal) == -1, "tcsetattr: Failed to set reverse terminal attributes."); - curses_screen = allocate (12 * (curses_screen_width + 2) * curses_screen_height + 8); + curses_screen = allocate (CURSES_OFFSET + CURSES_LENGTH * curses_screen_width * curses_screen_height + 1); for (key = ' '; key != '~'; ++key) { curses_unbind (key); @@ -58,9 +60,9 @@ void curses_initialize (void) { void curses_deinitialize (void) { curses_screen = deallocate (curses_screen); - out ("\033[2J\033[H", 7); + out ("\033[2J\033[H", string_length ("\033[2J\033[H")); - fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_old_terminal) == -1, "[!] tcsetattr: Failed to set terminal attributes."); + fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_old_terminal) == -1, "tcsetattr: Failed to set default terminal attributes."); } void curses_synchronize (void) { @@ -70,62 +72,69 @@ void curses_synchronize (void) { in (& curses_signal, 1); - curses_screen_size = 0; - if ((curses_signal >= ' ') && (curses_signal <= '~')) { curses_action [curses_signal - ' '] (); } - string_copy_limit (& curses_screen [curses_screen_size], "\033[H", 3); - curses_screen_size += 3; + curses_screen_offset (); } -void curses_blank (void) { - int i, j; - - for (i = 0; i != curses_screen_height; ++i) { - for (j = 0; j != curses_screen_width; ++j) { - curses_character (' ', EFFECT_NORMAL, COLOUR_WHITE, j, i); - } - } +void curses_screen_offset (void) { + string_copy_limit (& curses_screen [0], "\033[H", CURSES_OFFSET); + curses_screen_size = CURSES_OFFSET; } -void curses_character (char character, int effect, int colour, int x, int y) { - char format [13] = "\033[ ;3 m \033[0m"; +char * curses_screen_position (int x, int y) { + fatal_failure (x <= -1, "curses_screen_position: X position is beyond the lower bound."); + fatal_failure (y <= -1, "curses_screen_position: Y position is beyond the lower bound."); + fatal_failure (x >= curses_screen_width, "curses_screen_position: X position is beyond the upper bound."); + fatal_failure (y >= curses_screen_height, "curses_screen_position: Y position is beyond the upper bound."); - format [2] = (char) effect + '0'; - format [5] = (char) colour + '0'; - format [7] = character; - - string_copy_limit (& curses_screen [(y * (curses_screen_width + 2) + x) * 12 + 3], format, 12); - - curses_screen_size += 12; + return (& curses_screen [CURSES_LENGTH * (y * curses_screen_width + x) + CURSES_OFFSET]); } -void curses_append_character (char character, int effect, int colour) { - char format [13] = "\033[ ;3 m \033[0m"; +char * curses_format_character (char character, int colour, int effect) { + fatal_failure (character_is_invisible (character), "curses_format_character: Can not format invisible characters."); + fatal_failure (colour >= COLOUR_COUNT, "curses_format_character: Colour is invalid enumeration value."); + fatal_failure (effect >= EFFECT_COUNT, "curses_format_character: Effect is invalid enumeration value."); - format [2] = (char) effect + '0'; - format [5] = (char) colour + '0'; - format [7] = character; + curses_format [2] = (char) effect + '0'; + curses_format [5] = (char) colour + '0'; + curses_format [7] = character; - string_copy_limit (& curses_screen [curses_screen_size], format, 12); - - curses_screen_size += 12; + return (curses_format); } -void curses_append_string (char * string, int effect, int colour, int length) { +void curses_output_character (char character, int colour, int effect) { + out (curses_format_character (character, colour, effect), CURSES_LENGTH); +} + +void curses_render_character (char character, int colour, int effect, int x, int y) { + string_copy_limit (curses_screen_position (x, y), curses_format_character (character, colour, effect), CURSES_LENGTH); + + curses_screen_size += CURSES_LENGTH; +} +/* +void curses_output_string (char * string, int colour, int effect) { char format [8] = "\033[ ;3 m"; format [2] = (char) effect + '0'; format [5] = (char) colour + '0'; string_copy_limit (& curses_screen [curses_screen_size], format, 7); - curses_screen_size += 7; - string_copy_limit (& curses_screen [curses_screen_size], string, length); - curses_screen_size += length; + string_copy_limit (& curses_screen [curses_screen_size], string, string_length (string)); string_copy_limit (& curses_screen [curses_screen_size], "\033[0m", 4); - curses_screen_size += 4; + + curses_screen_size += 7 + string_length (string) + 4; +} + +void curses_render_string (char * string, int colour, int effect, int x, int y) { + int offset = 0; + int length = string_length (string); + + for (offset = 0; offset != length; (++offset, ++x)) { + curses_render_character (string [offset], colour, effect, x, y); + } } void curses_append_cursor (int cursor_x, int cursor_y) { @@ -141,29 +150,14 @@ void curses_append_cursor (int cursor_x, int cursor_y) { string_copy_limit (& curses_screen [curses_screen_size], format, 10); curses_screen_size += 10; } +*/ +void curses_blank (void) { + int i, j; -void curses_style (int effect, int colour) { - char format [8] = "\033[ ;3 m"; - - if ((effect == -1) || (colour == -1)) { - out ("\033[0m", 4); - } else { - format [2] = (char) effect + '0'; - format [5] = (char) colour + '0'; - - out (format, 7); - } -} - -void curses_clear (void) { - out ("\033[2J", 4); -} - -void curses_show_cursor (int show) { - if (show != 0) { - out ("\033[?25h", 6); - } else { - out ("\033[?25l", 6); + for (i = 0; i != curses_screen_height; ++i) { + for (j = 0; j != curses_screen_width; ++j) { + curses_render_character (' ', EFFECT_NORMAL, COLOUR_WHITE, j, i); + } } } diff --git a/xurses.h b/xurses.h index e0d411a..098e76d 100644 --- a/xurses.h +++ b/xurses.h @@ -13,11 +13,13 @@ #include #include -#include #include #include #include +#define CURSES_LENGTH ((int) sizeof ("\033[-;3-m-\033[0m") - 1) +#define CURSES_OFFSET ((int) sizeof ("\033[H") - 1) + extern int curses_active; extern int curses_cursor; extern char curses_signal; @@ -26,23 +28,26 @@ extern int curses_screen_height; extern int curses_screen_size; extern char * curses_screen; -extern void (* curses_action ['~' - ' ']) (void); +extern char curses_format [CURSES_LENGTH + 1]; + +extern void (* curses_action ['~' - ' ' + 1]) (void); extern struct termios curses_old_terminal; extern struct termios curses_new_terminal; -extern void curses_initialize (void); -extern void curses_deinitialize (void); -extern void curses_synchronize (void); +extern void curses_initialize (void); +extern void curses_deinitialize (void); +extern void curses_synchronize (void); +extern void curses_screen_offset (void); +extern char * curses_screen_position (int, int); +extern char * curses_format_character (char, int, int); + +extern void curses_output_character (char, int, int); +extern void curses_render_character (char, int, int, int, int); +/*extern void curses_append_string (char *, int, int, int); +extern void curses_append_cursor (int, int);*/ extern void curses_blank (void); -extern void curses_character (char, int, int, int, int); -extern void curses_append_character (char, int, int); -extern void curses_append_string (char *, int, int, int); -extern void curses_append_cursor (int, int); -extern void curses_style (int, int); -extern void curses_clear (void); -extern void curses_show_cursor (int); extern void curses_bind (char, void (*) (void)); extern void curses_unbind (char);