|
- /*
- * Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
- *
- * Xurses is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
- * And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
- * It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
- */
-
- #ifndef XURSES_SOURCE
- #define XURSES_SOURCE
-
- #include <xolatile/xurses.h>
-
- 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;
-
- void (* curses_action ['~' - ' ']) (void) = { 0 };
-
- struct termios curses_old_terminal;
- struct termios curses_new_terminal;
-
- void curses_initialize (void) {
- char key;
-
- struct winsize screen_dimension;
-
- fatal_failure (ioctl (STDOUT_FILENO, TIOCGWINSZ, & screen_dimension) == -1, "[!] ioctl: Failed to get terminal size.");
-
- 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.");
-
- curses_new_terminal = curses_old_terminal;
-
- curses_new_terminal.c_cc [VMIN] = (unsigned char) 0;
- curses_new_terminal.c_cc [VTIME] = (unsigned char) 1;
-
- curses_new_terminal.c_iflag &= (unsigned int) ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
- curses_new_terminal.c_oflag &= (unsigned int) ~(OPOST);
- 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.");
-
- curses_screen = allocate (12 * (curses_screen_width + 2) * curses_screen_height + 8);
-
- for (key = ' '; key != '~'; ++key) {
- curses_unbind (key);
- }
- }
-
- void curses_deinitialize (void) {
- curses_screen = deallocate (curses_screen);
-
- out ("\033[2J\033[H", 7);
-
- fatal_failure (tcsetattr (STDIN_FILENO, TCSAFLUSH, & curses_old_terminal) == -1, "[!] tcsetattr: Failed to set terminal attributes.");
- }
-
- void curses_synchronize (void) {
- curses_signal = '\0';
-
- out (curses_screen, curses_screen_size);
-
- 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;
- }
-
- 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_character (char character, int effect, int colour, int x, int y) {
- char format [13] = "\033[ ;3 m \033[0m";
-
- 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;
- }
-
- void curses_append_character (char character, int effect, int colour) {
- char format [13] = "\033[ ;3 m \033[0m";
-
- format [2] = (char) effect + '0';
- format [5] = (char) colour + '0';
- format [7] = character;
-
- string_copy_limit (& curses_screen [curses_screen_size], format, 12);
-
- curses_screen_size += 12;
- }
-
- void curses_append_string (char * string, int effect, int colour, int length) {
- 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], "\033[0m", 4);
- curses_screen_size += 4;
- }
-
- void curses_append_cursor (int cursor_x, int cursor_y) {
- char format [11] = "\033[000;000H";
-
- 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_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);
- }
- }
-
- void curses_bind (char key, void (* action) (void)) {
- curses_action [key - ' '] = action;
- }
-
- void curses_unbind (char key) {
- curses_action [key - ' '] = curses_idle;
- }
-
- void curses_idle (void) {
- return;
- }
-
- void curses_exit (void) {
- curses_active = 0;
- }
-
- #endif
|