This commit is contained in:
visionmercer 2026-06-01 09:16:39 +02:00
commit d146c400cd
2 changed files with 557 additions and 0 deletions

129
terminkey.h Normal file
View file

@ -0,0 +1,129 @@
// #include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#include <conio.h>
#else
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#endif
// Special key codes (unified across platforms)
#define KEY_ARROW_UP 1001
#define KEY_ARROW_DOWN 1002
#define KEY_ARROW_RIGHT 1003
#define KEY_ARROW_LEFT 1004
int terminkey();
void echooff();
void echoon();
int termwidth();
#ifdef _WIN32
int terminkey() {
if (_kbhit()) {
int ch = _getch();
// Handle Windows arrow keys
if (ch == 224) {
int next = _getch();
switch (next) {
case 72: return KEY_ARROW_UP;
case 80: return KEY_ARROW_DOWN;
case 75: return KEY_ARROW_LEFT;
case 77: return KEY_ARROW_RIGHT;
default: return next;
}
}
return ch;
}
return -1;
}
void echooff() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~ENABLE_ECHO_INPUT);
}
void echoon() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode | ENABLE_ECHO_INPUT);
}
int termwidth() {
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(hStdout, &csbi)) {
return csbi.srWindow.Right - csbi.srWindow.Left + 1;
}
return -1;
}
#else
int terminkey() {
struct termios oldt, newt;
int ch;
int oldf;
// Save existing terminal settings
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
// Disable buffering and echoing
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
// Set STDIN to non-blocking
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
// Handle Unix arrow keys (ESC [ A/B/C/D)
if (ch == 27) {
int next1 = getchar();
if (next1 == '[') {
int next2 = getchar();
switch (next2) {
case 'A': ch = KEY_ARROW_UP; break;
case 'B': ch = KEY_ARROW_DOWN; break;
case 'C': ch = KEY_ARROW_RIGHT; break;
case 'D': ch = KEY_ARROW_LEFT; break;
}
}
}
// Restore terminal settings
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
return ch;
}
void echooff() {
struct termios tty;
tcgetattr(STDIN_FILENO, &tty);
tty.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &tty);
}
void echoon() {
struct termios tty;
tcgetattr(STDIN_FILENO, &tty);
tty.c_lflag |= ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &tty);
}
int termwidth() {
struct winsize w;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
return w.ws_col;
}
return -1;
}
#endif