Я работаю над программой терминала для распознавания отдельных нажатий клавиш, включая клавиши клавиатуры, но я бы не стал делать это в режиме проклятий / программы, если это возможно. Вместо того, чтобы заново изобретать колесо с помощью terminfo и какого-либо отображения или древовидной структуры для быстрого сопоставления клавиш клавиатуры, я подумал, что мог бы просто использовать проклятия и использовать tcgetattr()
и tcsetattr()
, чтобы делать то, что я хочу, вне режима проклятий, все еще используя проклятия I / O функции, чтобы сделать перевод клавиш клавиатуры для меня. К моему большому удивлению, это работает (Linux, ncurses 6.1.20180127):
/**
* Most error checking elided for brevity.
*/
#include <stdio.h> // printf
#include <string.h> // memcpy
#include <curses.h>
#include <termios.h> // tcgetattr, tcsetattr
int main(void)
{
struct termios curr, new_shell_mode;
int c, fd;
SCREEN *sp;
FILE *ttyf;
/*
* Initialize desired abilities in curses.
* This unfortunately clears the screen, so
* a refresh() is required, followed by
* endwin().
*/
ttyf = fopen("/dev/tty", "r+b");
fd = fileno(ttyf);
sp = newterm(NULL, ttyf, ttyf);
raw();
noecho();
nonl();
keypad(stdscr, TRUE);
refresh();
// Save the current curses mode TTY attributes for later use.
tcgetattr(fd, &curr);
endwin();
/*
* Set the shell/non-curses mode TTY attributes to
* match those of program/curses mode (3 attempts).
*/
memcpy(&new_shell_mode, &curr, sizeof curr);
for (c = 0; c < 3; c++) {
tcsetattr(fd, TCSADRAIN, &new_shell_mode);
tcgetattr(fd, &curr);
if (0 == memcmp(&new_shell_mode, &curr, sizeof curr))
break;
}
// If new shell mode could fully be set, get a key press.
if (c != 3)
c = getch();
reset_shell_mode();
delscreen(sp);
fclose(ttyf);
printf("%02X\n", c);
return 0;
}
Однако, учитывая, что я вышел из режима проклятий, действительно ли безопасно / переносимо все еще использовать getch()
указанным способом?
Или мне нужно выбрать более сложный путь использования setupterm()
для загрузки БД terminfo и перебрать массив strnames
, вызывая tigetstr()
для каждого, плюс вручную установить свои собственные флаги termios и заняться чтением Сама клавиша?
Ничто в спецификации XSI Curses, по-видимому, не запрещает этого, при условии, что stdscr
остается действительным, что, по-видимому, либо до выхода из программы, либо до вызова delwin()
, я могу продолжать использовать его, и поскольку подключено stdscr
к моему ttyf
файлу, который является терминалом, я могу использовать его для нажатия клавиш, не прибегая к самостоятельной обработке.