diff --git a/compile.sh b/compile.sh new file mode 100644 index 0000000..c041afa --- /dev/null +++ b/compile.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -xe + +gcc -g -ansi -Wall -Wextra -Wpedantic -Werror -c -o xurses.o xurses.c + +exit diff --git a/install.sh b/install.sh index bcab200..35a66d0 100644 --- a/install.sh +++ b/install.sh @@ -6,5 +6,6 @@ mkdir -p /usr/include/xolatile cp xurses.h /usr/include/xolatile/xurses.h cp xurses.c /usr/include/xolatile/xurses.c +cp xurses.o /usr/include/xolatile/xurses.o exit diff --git a/xurses.c b/xurses.c index c534677..ddfe69d 100644 --- a/xurses.c +++ b/xurses.c @@ -11,27 +11,79 @@ #include -int curses_active = 1; -int curses_cursor = 0; -char curses_signal = '\0'; -int curses_screen_width = 0; -int curses_screen_height = 0; -int curses_screen_size = 0; -char * curses_screen = NULL; +#include +#include +#include +#include -char curses_format [CURSES_LENGTH + 1] = "\033[-;3-m-\033[0m"; +#define CURSES_LENGTH ((int) sizeof ("\033[-;3-m-\033[0m") - 1) +#define CURSES_OFFSET ((int) sizeof ("\033[H") - 1) +#define CURSES_RETURN ((int) sizeof ("\r\n") - 1) -void (* curses_action [SIGNAL_COUNT]) (void) = { 0 }; +static int curses_stop = SIGNAL_Q; +static int curses_signal = SIGNAL_NONE; +static int curses_screen_width = 0; +static int curses_screen_height = 0; +static int curses_screen_size = 0; +static char * curses_screen = NULL; -struct termios curses_old_terminal; -struct termios curses_new_terminal; +static char curses_format [CURSES_LENGTH + 1] = "\033[-;3-m-\033[0m"; -void curses_initialize (void) { +static void (* curses_action [SIGNAL_COUNT]) (void) = { 0 }; + +static struct termios curses_old_terminal; +static struct termios curses_new_terminal; + +int curses_active = 0; + +static void curses_free (void) { + curses_screen = deallocate (curses_screen); + + terminal_clear (); + + fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_old_terminal) == -1, "tcsetattr: Failed to set default terminal attributes."); +} + +static void curses_screen_offset (void) { + string_copy (& curses_screen [0], "\033[H"); + curses_screen_size = CURSES_OFFSET; +} + +static char * curses_screen_position (int x, int y) { + fatal_failure (x <= -1, "curses_screen_position: X position is below the lower bound."); + fatal_failure (y <= -1, "curses_screen_position: Y position is below the lower bound."); + fatal_failure (x >= curses_screen_width, "curses_screen_position: X position is above the upper bound."); + fatal_failure (y >= curses_screen_height, "curses_screen_position: Y position is above the upper bound."); + + return (& curses_screen [CURSES_LENGTH * (y * curses_screen_width + x) + y * CURSES_RETURN + CURSES_OFFSET]); +} + +static char * curses_format_character (char character, int colour, int effect) { + log_in (LOG_WARNING, character_is_invisible (character), "curses_format_character: Can not format invisible characters."); + log_in (LOG_FAILURE, colour >= COLOUR_COUNT, "curses_format_character: Colour is invalid enumeration value."); + log_in (LOG_FAILURE, effect >= EFFECT_COUNT, "curses_format_character: Effect is invalid enumeration value."); + + curses_format [2] = (char) (effect % EFFECT_COUNT) + '0'; + curses_format [5] = (char) (colour % COLOUR_COUNT) + '0'; + curses_format [7] = character; + + log_out ("curses.log"); + + return (curses_format); +} + +static void curses_idle (void) { + return; +} + +void curses_configure (void) { struct winsize screen_dimension; char signal = 0; char offset = 0; + atexit (curses_free); + fatal_failure (ioctl (STDOUT_FILENO, TIOCGWINSZ, & screen_dimension) == -1, "ioctl: Failed to get terminal dimensions."); curses_screen_width = (int) screen_dimension.ws_col; @@ -64,21 +116,13 @@ void curses_initialize (void) { for (offset = 0; offset != curses_screen_height - 1; ++offset) { string_copy (& curses_screen [CURSES_LENGTH * curses_screen_width * offset + CURSES_OFFSET], "\r\n"); } -} - -void curses_deinitialize (void) { - curses_screen = deallocate (curses_screen); - - terminal_clear (); - fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_old_terminal) == -1, "tcsetattr: Failed to set default terminal attributes."); + curses_active = 1; } void curses_synchronize (void) { curses_signal = '\0'; -/* - out (curses_screen, curses_screen_size); -*/ + out (curses_screen, CURSES_OFFSET + CURSES_LENGTH * curses_screen_width * curses_screen_height/* + curses_screen_height * CURSES_RETURN*/); in (& curses_signal, 1); @@ -90,6 +134,11 @@ void curses_synchronize (void) { default: curses_signal = SIGNAL_NONE; break; } + if (curses_signal == curses_stop) { + curses_active = 0; + return; + } + if ((curses_signal > SIGNAL_ANY) && (curses_signal < SIGNAL_COUNT)) { curses_action [curses_signal] (); } @@ -97,92 +146,18 @@ void curses_synchronize (void) { curses_screen_offset (); } -void curses_configure (void) { - atexit (curses_deinitialize); - - curses_initialize (); -} - -void curses_screen_offset (void) { - string_copy (& curses_screen [0], "\033[H"); - curses_screen_size = CURSES_OFFSET; -} - -char * curses_screen_position (int x, int y) { - fatal_failure (x <= -1, "curses_screen_position: X position is below the lower bound."); - fatal_failure (y <= -1, "curses_screen_position: Y position is below the lower bound."); - fatal_failure (x >= curses_screen_width, "curses_screen_position: X position is above the upper bound."); - fatal_failure (y >= curses_screen_height, "curses_screen_position: Y position is above the upper bound."); - - return (& curses_screen [CURSES_LENGTH * (y * curses_screen_width + x) + y * CURSES_RETURN + CURSES_OFFSET]); -} - -char * curses_format_character (char character, int colour, int effect) { - log_in (LOG_WARNING, character_is_invisible (character), "curses_format_character: Can not format invisible characters."); - log_in (LOG_FAILURE, colour >= COLOUR_COUNT, "curses_format_character: Colour is invalid enumeration value."); - log_in (LOG_FAILURE, effect >= EFFECT_COUNT, "curses_format_character: Effect is invalid enumeration value."); - - curses_format [2] = (char) (effect % EFFECT_COUNT) + '0'; - curses_format [5] = (char) (colour % COLOUR_COUNT) + '0'; - curses_format [7] = character; - - log_out ("curses.log"); - - return (curses_format); -} - -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 x, int y, int colour, int effect) { +void curses_render_character (char character, int colour, int effect, int x, int y) { string_copy (curses_screen_position (x, y), curses_format_character (character, colour, effect)); 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); - 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 += 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) { - char format [11] = "\033[000;000H"; +void curses_render_background (char character, int colour, int effect) { + int x, y; - format [4] = (char) (cursor_y / 1) % 10 + '0'; - format [3] = (char) (cursor_y / 10) % 10 + '0'; - format [2] = (char) (cursor_y / 100) % 10 + '0'; - format [8] = (char) (cursor_x / 1) % 10 + '0'; - format [7] = (char) (cursor_x / 10) % 10 + '0'; - format [6] = (char) (cursor_x / 100) % 10 + '0'; - - string_copy_limit (& curses_screen [curses_screen_size], format, 10); - curses_screen_size += 10; -} -*/ -void curses_blank (void) { - int i, j; - - 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); + for (y = 0; y != curses_screen_height; ++y) { + for (x = 0; x != curses_screen_width; ++x) { + curses_render_character (character, colour, effect, x, y); } } } @@ -195,12 +170,8 @@ void curses_unbind (int signal) { curses_action [signal] = curses_idle; } -void curses_idle (void) { - return; -} - -void curses_exit (void) { - curses_active = 0; +void curses_exit (int signal) { + curses_stop = signal; } #endif diff --git a/xurses.h b/xurses.h index 292bfb3..2c72383 100644 --- a/xurses.h +++ b/xurses.h @@ -11,50 +11,16 @@ #include -#include -#include -#include -#include +extern int curses_active; -#define CURSES_LENGTH ((int) sizeof ("\033[-;3-m-\033[0m") - 1) -#define CURSES_OFFSET ((int) sizeof ("\033[H") - 1) -#define CURSES_RETURN ((int) sizeof ("\r\n") - 1) +extern void curses_configure (void); +extern void curses_synchronize (void); -extern int curses_active; -extern int curses_cursor; -extern char curses_signal; -extern int curses_screen_width; -extern int curses_screen_height; -extern int curses_screen_size; -extern char * curses_screen; +extern void curses_bind (int signal, void (* action) (void)); +extern void curses_unbind (int signal); +extern void curses_exit (int signal); -extern char curses_format [CURSES_LENGTH + 1]; - -extern void (* curses_action [SIGNAL_COUNT]) (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_configure (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_bind (int, void (*) (void)); -extern void curses_unbind (int); - -extern void curses_idle (void); -extern void curses_exit (void); +extern void curses_render_character (char character, int colour, int effect, int x, int y); +extern void curses_render_background (char character, int colour, int effect); #endif