//=-------------------------------------------------------------------------=// // Terminal management tools // // // // Copyright © 2021 The Gem-graph Project // // // // This file is part of gem-graph. // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as // // published by the Free Software Foundation, either version 3 of the // // License, or (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU Affero General Public License for more details. // // // // You should have received a copy of the GNU Affero General Public License // // along with this program. If not, see . // //=-------------------------------------------------------------------------=// #ifndef BASE_H #include "../include/base.h" #endif #include #include #include #include #define C_CLEARSCREEN "\e[2J" #define C_CLEARLINE "\e[2K" #define C_CURSORLEFT "\e[1D" #define C_CURSORRIGHT "\e[1C" #define C_SAVE_CURSORPOS "\e7" #define C_RESTORE_CURSORPOS "\e8" #define C_COLOR_RED "\e[01;31m" #define C_COLOR_YELLOW "\e[00;33m" #define C_COLOR_GREEN "\e[00;32m" #define C_COLOR_BLUE "\e[01;34m" #define C_COLOR_REVERSE "\e[7m" #define C_COLOR_NORMAL "\e[0m" #define C_COLOR_BLACK_ON_GREEN "\e[30;42m" #define C_COLOR_LIGHTWHITE_ON_GREEN "\e[47;42m" #define C_COLOR_LIGHTWHITE_ON_GREY "\e[47;100m" #define C_COLOR_BLACK_ON_LIGHTGREY "\e[30;102m" #define C_COLOR_WHITE_ON_BLUE "\e[107;44m" #define NON_BLOCKING 1 volatile struct winsize terminalSize; // // Get a character code from the keyboard // static inline int getch(bool nonBlocking) { int buf = 0; // old terminal struct termios old = {0}; // force flush stdout fflush(stdout); // Set non-blocking mode if asked if(nonBlocking) fcntl(0, F_SETFL, O_NONBLOCK); if(tcgetattr(0, &old) < 0) { printLog("%sError getting terminal settings! (%s)\n", C_COLOR_RED, strerror(errno)); return -1; } old.c_lflag &= ~ICANON; // disable buffered I/O old.c_lflag &= ~ECHO; // set no echo mode if(tcsetattr(0, TCSANOW, &old) < 0) { printLog("%sError setting terminal settings! (%s)\n", C_COLOR_RED, strerror(errno)); return -1; } buf = getchar(); if(buf < 0) { // Check target busy (try again) if(errno == EAGAIN) return 0; printLog("%sError reading character! (%s)\n", C_COLOR_RED, strerror(errno)); return -1; } old.c_lflag |= ICANON; // enable buffered I/O old.c_lflag |= ECHO; // set echo mode if(tcsetattr(0, TCSADRAIN, &old) < 0) { printLog("%sError resetting terminal settings! (%s)\n", C_COLOR_RED, strerror(errno)); return -1; } // Reset blocking mode if(nonBlocking) fcntl(0, F_SETFL, 0); return buf; } // // Get the screen size // static inline void getScreenSize(int signum) { // Get current terminal size ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminalSize); } // // Set cursor location // static inline void setCursorLocation(char x, char y) { printf("\x1b[%d;%dH", y, x); } // // Save cursor location // static inline void saveCursorLocation(void) { printf(C_SAVE_CURSORPOS); } // // Restore cursor location // static inline void restoreCursorLocation(void) { printf(C_RESTORE_CURSORPOS); } // // Move cursor location to the right // static inline void moveCursorForward(void) { printf(C_CURSORRIGHT); } // // Move cursor location to the left // static inline void moveCursorBackward(void) { printf(C_CURSORLEFT); } // // Clear screen // static inline void clearScreen(void) { printf(C_CLEARSCREEN); setCursorLocation(1,1); fflush(stdout); }