|
|
@@ -0,0 +1,139 @@ |
|
|
|
/* |
|
|
|
* 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 * curses_screen_height + 8); |
|
|
|
|
|
|
|
string_copy_limit (& curses_screen [0], "\033[2J\033[H", 7); |
|
|
|
|
|
|
|
for (key = ' '; key != '~'; ++key) { |
|
|
|
curses_unbind (key); |
|
|
|
} |
|
|
|
|
|
|
|
//~write (STDOUT_FILENO, "\033[25h", sizeof ("\033[25h")); |
|
|
|
} |
|
|
|
|
|
|
|
void curses_deinitialize (void) { |
|
|
|
free (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, 12 * curses_screen_width * curses_screen_height + 8); |
|
|
|
|
|
|
|
in (& curses_signal, 1); |
|
|
|
|
|
|
|
if ((curses_signal < ' ') || (curses_signal > '~')) { |
|
|
|
return; |
|
|
|
} else { |
|
|
|
curses_action [curses_signal - ' '] (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void curses_character (char character, int effect, int colour, int x, int y) { |
|
|
|
char format [12] = "\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 + x) * 12 + 7], format, 12); |
|
|
|
} |
|
|
|
|
|
|
|
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_move_cursor (int x, int y) { |
|
|
|
out ("\033[H", 4); /* yx */ |
|
|
|
} |
|
|
|
|
|
|
|
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 |