ncurses "get_wch" 函数行为

ncurses "get_wch" function behavior

我试图了解 ncurses 中的 get_wch 函数是如何工作的。

这是我用来在 TTY、terminator 和 konsole 下测试的一段代码:

 #include <stdlib.h>
 #include <curses.h>
 #include <locale.h>
 
 int main(void)
 {
     // initialize curses
     initscr();
     setlocale(LC_ALL, "");   // Just a check to see if something change with it
     wint_t char_code;
     int key_code = get_wch(&char_code);
     char truc [20];
     sprintf(truc, "%d / %d", key_code, char_code);
     refresh();
     getch();
     endwin();
     
     printf("%d\n", KEY_CODE_YES);
     printf(truc);
     printf("\n");
     return 0;
 }

当我按下像 'a' 或 '?' 这样的“经典”键时,我得到一个 char_code(我想是 UTF-8 代码)。但是当我按下像 F1 或 F12 这样的功能键时,我得到一个 char_code 27,和一个 key_code 0, 除了 F11 (key_code : KEY_CODE_YES, char_code: 410).

文档说:

When get_wch, wget_wch, mvget_wch, and mvwget_wch functions successfully report the pressing of a function key, they return KEY_CODE_YES. When they successfully report a wide character, they return OK.

F1到F12就是所谓的“功能键”?如果我是对的,你能解释一下为什么当我按下 Fx 键时函数 return 0 作为 key_code 吗?

只有当 keypad 设置为 true 时,您才会得到 KEY_CODE_YES,请参阅 keypad 手册页:

The keypad option enables the keypad of the user's terminal. If enabled (bf is TRUE), 
the user can press a function key (such as an arrow key) and wgetch returns a single value 
representing the function key, as in KEY_LEFT. If disabled (bf is FALSE), curses does not 
treat function keys specially and the program has to interpret the escape sequences 
itself. If the keypad in the terminal can be turned on (made to transmit) and off (made to 
work locally), turning on this option causes the terminal keypad to be turned on when 
wgetch is called. The default value for keypad is false.

并且您没有获得密钥代码 0,而是来自 get_wch 的成功状态 OK,请参阅相关联机帮助页。

没有它,您将必须获得多个 char_code 才能获得关键代码,例如:

     wint_t char_code;
     wint_t char_code2 = 0, char_code3 = 0;
     int key_code = get_wch(&char_code);
     if (key_code == OK) key_code = get_wch(&char_code2);
     if (key_code == OK) key_code = get_wch(&char_code3);

对于功能键,转义码在char_code(0x27),功能码在char_code2(0x4b),具体功能key_code在char_code3.

EDIT 正如@dratenik 所注意到的,使用 xterm/VT220+ 终端,F5-F12 功能键输出四个 char_code,所以你需要当你在 char_code2 中得到 [ (0x5b) 并且在 char_code3 中得到 1 (0x31) 时查询另一个 char_code 以获取特定的功能键 key_code 用于这些功能键。您可以在@dratenik 提供的 this useful link 中找到可能的密钥代码。