diff --git a/include/terminal.h b/include/terminal.h
new file mode 100644
index 0000000..485591c
--- /dev/null
+++ b/include/terminal.h
@@ -0,0 +1,173 @@
+//=-------------------------------------------------------------------------=//
+// 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);
+}
+
diff --git a/src/cli.c b/src/cli.c
index e9786e8..d3ebb32 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -85,36 +85,36 @@ void decorateMonitor(int signum)
screenTitleText
);
setCursorLocation(terminalSize.ws_col / 3 * 2, 2);
- printf("%s%s (void)",
+ printf("%s%s",
C_COLOR_NORMAL C_COLOR_BLACK_ON_GREEN,
infosTitleText
);
- setCursorLocation(terminalSize.ws_col / 3 * 2, 3);
+ setCursorLocation(terminalSize.ws_col / 3 * 2, 4);
printf("%s%s%s (void)",
C_COLOR_NORMAL C_COLOR_BLACK_ON_LIGHTGREY,
infosNameText,
C_COLOR_NORMAL
);
- setCursorLocation(terminalSize.ws_col / 3 * 2, 4);
+ setCursorLocation(terminalSize.ws_col / 3 * 2, 6);
printf("%s%s%s (void)",
C_COLOR_BLACK_ON_GREEN,
infosStatusText,
C_COLOR_NORMAL
);
- setCursorLocation(terminalSize.ws_col / 3 * 2, 5);
+ setCursorLocation(terminalSize.ws_col / 3 * 2, 8);
printf("%s%s%s (void)",
C_COLOR_BLACK_ON_LIGHTGREY,
infosOwnerText,
C_COLOR_NORMAL
);
- setCursorLocation(terminalSize.ws_col / 3 * 2, 6);
+ setCursorLocation(terminalSize.ws_col / 3 * 2, 10);
printf("%s%s%s (void)",
C_COLOR_BLACK_ON_GREEN,
infosSchedulerText,
C_COLOR_NORMAL
);
- setCursorLocation(terminalSize.ws_col / 3 * 2, 7);
+ setCursorLocation(terminalSize.ws_col / 3 * 2, 12);
printf("%s%s%s (void)",
C_COLOR_BLACK_ON_LIGHTGREY,
infosScThreadsText,
@@ -127,6 +127,13 @@ void decorateMonitor(int signum)
printf(" ");
}
+ setCursorLocation(1, terminalSize.ws_row);
+ printf(C_COLOR_NORMAL);
+ for (int i = 0; i < terminalSize.ws_col; i++) {
+ printf(" ");
+ }
+
+ setCursorLocation(1, terminalSize.ws_row);
printf("%sQ%s Quit\t%sS%s Start/Stop",
C_COLOR_NORMAL C_COLOR_REVERSE,
C_COLOR_NORMAL,