当使用newterm()

时间:2017-08-01 14:08:47

标签: c ubuntu ncurses

更新:正如Thomas在评论中所建议的那样,shell肯定会在ncurses到达之前缓冲输入。我将ncurses调试到文件描述符上的原始read(),我确认了块,直到我在新终端中输入两个字符。我确实找到了一个丑陋的黑客来解决这个问题 - 我可以用另一个不干扰终端的应用程序(例如xclock)来吸引shell,然后连接到终端。没有更多缓冲 - ncurses成功读取每个字符。

原始问题:我正在尝试编写一个控制多个终端的ncurses程序。我一直在使用newterm() API,它允许我成功创建新的SCREEN句柄。但是,当我尝试从新终端读取输入时,getch()忽略我键入的第一个字符,并且仅在输入第二个字符时返回输入。

以下是我初始化屏幕的方式:

const char *term_fn = "/dev/pts/18"; // Filename of other terminal
FILE *term_fp = fopen(term_fn, "r+");
SCREEN *term = newterm(NULL, term_fp, term_fp);
set_term(term);                      // Ensure we're using the new screen
keypad(stdscr, TRUE);                // Make ncurses interpret function keys
nodelay(stdscr, FALSE);              // Make getch() blocking
cbreak();                            // Don't buffer input until newline
echo();                              // Echo the keyboard input back

我已经仔细检查过文件是否正确打开了,ncurses为我初始化了一个新的SCREEN。但是,当我尝试读取输入getch()块时,直到我输入2个字符。例如,当我运行以下代码时,重复读取&显示输入,直到输入'q':

void get_and_print_input() {
  char cur;
  mvprintw(0, 0, "Please enter a character: ");
  refresh();
  do {
    /* getch() will *not* return until I type 2 characters */
    cur = getch();
    if(cur != ERR) {
      mvprintw(1, 0, "Got a character: '%c'", cur);
      move(0, 26);
      refresh();
      if(cur == 'q') break;
      else cur = ERR;
    }
  } while(cur == ERR);
}

当我输入'a'时,我得到以下示例输出,等待30秒然后输入'b':

Please enter a character: ab
Got a character: 'b'

我在Ubuntu 16.04 LTS上运行,我的TERM环境变量是“屏幕”,虽然我正在使用tmux。我应该注意,当我使用标准屏幕时,getch()的行为符合预期(即,在输入单个字符时返回),即,而不是打开一个新的终端,我只需要调用initscr()。我是否错误地初始化了新屏幕?

下面的

编辑是一个独立的示例。为了运行该程序,我打开了2个终端 - 一个运行程序的终端,称为终端A,另一个终端由ncurses,终端B控制。该程序将终端B的文件名作为输入,如{{ 1}}命令(例如,我传递它tty)。在终端A中运行的程序打开文件描述符&用于控制终端B的屏幕。然后调用-f /dev/pts/18 - 我输入字符,程序在终端B上打印所有输出。在检测到用户输入'q'后,程序清除所有数据结构和回报。

get_and_print_input()

编辑2:在将字符传递给ncurses之前,shell似乎正在进行一些缓冲。当我使用#include <unistd.h> #include <assert.h> #include <ncurses.h> static const char *term_fn = NULL; static FILE *term_fp = NULL; static SCREEN *term = NULL; void parse_args(int argc, char **argv) { int c; while((c = getopt(argc, argv, "f:")) != -1) { switch(c) { case 'f': term_fn = optarg; break; default: break; } } } void get_and_print_input() { char cur; mvprintw(0, 0, "Please enter a character: "); refresh(); do { cur = getch(); if(cur != ERR) { mvprintw(1, 0, "Got a character: '%c'", cur); move(0, 26); refresh(); if(cur == 'q') break; else cur = ERR; } } while(cur == ERR); } int main(int argc, char **argv) { /* Set up all data structures */ parse_args(argc, argv); assert(term_fn != NULL && "Must supply a terminal file"); term_fp = fopen(term_fn, "r+"); assert(term_fp && "Couldn't open terminal file"); term = newterm(NULL, term_fp, term_fp); assert(term && "Couldn't open terminal"); /* Configure screen */ set_term(term); keypad(stdscr, TRUE); nodelay(stdscr, FALSE); cbreak(); echo(); get_and_print_input(); /* Cleanup */ endwin(); delscreen(term); fclose(term_fp); } 而不是noecho()时,它仍会回显我输入的第一个字符,但不会回显第二个字符。例如,使用与上面相同的输入:

echo()

0 个答案:

没有答案