//=-------------------------------------------------------------------------=//
// 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 TermWindowSize;
/* -------------------------------------------------------------------------- */
// -------------------------------------------------------------------------- //
// Get a character code from the keyboard //
// -------------------------------------------------------------------------- //
static inline int TermGetch(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 TermGetScreenSize(int signum)
{
// Get current terminal size
ioctl(STDOUT_FILENO, TIOCGWINSZ, &TermWindowSize);
}
// -------------------------------------------------------------------------- //
// Set cursor location //
// -------------------------------------------------------------------------- //
static inline void TermSetCursorLocation(char x, char y)
{
printf("\x1b[%d;%dH", y, x);
}
// -------------------------------------------------------------------------- //
// Save cursor location //
// -------------------------------------------------------------------------- //
static inline void TermSaveCursorLocation(void)
{
printf(C_SAVE_CURSORPOS);
}
// -------------------------------------------------------------------------- //
// Restore cursor location //
// -------------------------------------------------------------------------- //
static inline void TermRestoreCursorLocation(void)
{
printf(C_RESTORE_CURSORPOS);
}
// -------------------------------------------------------------------------- //
// Move cursor location to the right //
// -------------------------------------------------------------------------- //
static inline void TermMoveCursorForward(void)
{
printf(C_CURSORRIGHT);
}
// -------------------------------------------------------------------------- //
// Move cursor location to the left //
// -------------------------------------------------------------------------- //
static inline void TermMoveCursorBackward(void)
{
printf(C_CURSORLEFT);
}
// -------------------------------------------------------------------------- //
// Clear screen //
// -------------------------------------------------------------------------- //
static inline void TermClearScreen(void)
{
printf(C_CLEARSCREEN);
TermSetCursorLocation(1,1);
fflush(stdout);
}