[英]How to set terminal background color on linux terminal without using ncurses?
[英]How to direct NCurses output to a serial terminal on boot from Linux?
我一直在编写代码来使用 ncurses++ 库显示菜单和屏幕。 期望的结果是通过串行终端接口输出这些菜单和屏幕。
我可以使用调用的基本 C ncurses 库成功地做到这一点。
if( (FDTERM = fopen("/dev/ttyS0", "r+")) != NULL )
{
if(FDTERM == NULL)
{
fprintf(stderr, "Error opening device: %s.\n", ncurses_device);
}
/* Set Screen */
MY_SCREEN = newterm(NULL, FDTERM, FDTERM);
if(MY_SCREEN != NULL)
{
/* Set the terminal */
set_term(MY_SCREEN);
}
}
为了让它在 C++ 中工作,我写了一些拦截.c 代码来覆盖在 cursesw.cc 中对 ::initscr() 的调用实际调用的内容
#define ncurses_device "/dev/ttyS0"
NCURSES_EXPORT(WINDOW *) initscr(void)
{
WINDOW *result;
pthread_mutex_lock(&CUSTOM_LOCK);
if (!CUSTOM_INITIALIZED)
{
CUSTOM_INITIALIZED = true;
if( (FDTERM = fopen(ncurses_device, "r+")) != NULL )
{
if(FDTERM == NULL)
{
fprintf(stderr, "Error opening device: %s.\n", ncurses_device);
}
/* Set Screen */
MY_SCREEN = newterm(NULL, FDTERM, FDTERM);
if(MY_SCREEN != NULL)
{
/* Set the terminal */
set_term(MY_CDU_SCREEN);
}
/* def_shell_mode - done in newterm/_nc_setupscreen */
def_prog_mode();
}
else
{
CUSTOM_INITIALIZED = true;
NCURSES_CONST char *name;
if ((name = getenv("TERM")) == 0 || *name == '\0')
{
static char unknown_name[] = "unknown";
name = unknown_name;
}
if (newterm(name, stdout, stdin) == 0)
{
fprintf(stderr, "Error opening terminal: %s.\n", name);
result = NULL;
}
}
}
#if NCURSES_SP_FUNCS
#ifdef CURRENT_SCREEN
NCURSES_SP_NAME(def_prog_mode) (CURRENT_SCREEN);
#else
NCURSES_SP_NAME(def_prog_mode) (SP);
#endif
#else
def_prog_mode();
#endif
result = stdscr;
pthread_mutex_unlock(&CUSTOM_LOCK);
return Win(result);
}
如果可用,intercept.c 允许使用定义的设备。 它还允许 initscr() 回退到使用当前终端的默认行为。
这在用于调试时有效,但我觉得必须有更好的方法来设置 NCurses 或环境以将 NCurses 输出定向到所需的串行端口。
由于没有可用的终端定义,因此在启动时执行代码时,上述解决方案现在不起作用。
正在开发它以支持 RHEL 7 和 6。一些研究似乎指向使用 getty、agetty 或通过编辑 start-tty.conf 创建一个新的环境服务,如上所述( https://unix.stackexchange.com/a/ 318647 )。
但另一个问题是将 NCurses++ 指向正确的环境输出。 从我在 NCurses 源代码中看到的内容来看,::initscr() 似乎是从 cursesw.cc 中默认调用的,这使得将 NCurses 指向新环境变得更加困难。
如何设置 NCurses++ 以输出到指定的 tty?
如何正确设置 NCurses 在系统启动时使用的环境?
更新代码以执行以下操作:
// Save the current stdin/stdout file descriptors
int saved_stdin = dup(fileno(stdin));
int saved_stdout = dup(fileno(stdout));
// Set the stdin/stdout to the desired device
freopen(ncurses_device, "w+", stdout);
freopen(ncurses_device, "r+", stdin);
// Initialize the NCursesMenu
NCursesMenu *m_pMenu = new NCursesMenu(m_pMenuItems);
// Restore the saved_stdin/stdout to the correct locations
dup2(saved_stdin, STDIN_FILENO);
dup2(saved_stdout, STDOUT_FILENO);
// Close the saved_stdin/stdout file descriptors
close(saved_stdin);
close(saved_stdout);
这让Ncurses把复制当前FILE *定义这里的newterm,但一旦标准输入/输出文件*恢复到保存的文件描述符的操作都将丢失。 如果设备仅指向新设备,则它适用于 NCurses,但所有调试/测试信息不可见,因为它被当前终端中的 NCurses 覆盖。
initscr
不对设备做任何假设:它在初始化时使用当前的输入/输出标准输入和标准输出(并且通过newterm
、 setupterm
,它复制文件描述符)。
如果您的应用程序(或环境/脚本)将这些流设置为您想要连接的设备,那么对于 C++ 接口来说应该足够了。 ncurses 不使用 C+ cout等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.