Ncurses,如果我在C

时间:2017-11-18 20:12:37

标签: c cygwin ncurses xterm mintty

这是代码:

#include <curses.h>
int main() {
  initscr();
  curs_set(2);
  for(int i=0;i<COLS;i++){ //COLS NUMERO MASSIMO DI COLONNE
      mvaddch(0,i,'*');
      mvaddch(LINES-1,i,'*'); //LINES NUMERO MASSIMO RIGHE SE PARTO DALL'ULTIMO RIGA = (LINES -1)
      }
  refresh();
  endwin(); 
  return 0; 
}

一切都好,但是如果我调整cygwin的窗口大小,屏幕就会变空。我有一个小小的cygwin。

2 个答案:

答案 0 :(得分:1)

这个例子有误导性:

  • 如果ncurses因调整大小而清除了屏幕,那么您将有一个getch来阻止程序退出(以及捕获KEY_RESIZE),
  • 但示例会在屏幕上写下一些字符然后退出。

如果您的终端(例如mintty)使用xterm终端描述,它将暂时切换到备用屏幕(这些字符被写入的地方),以及退出ncurses(按照终端说明中的说明)切换回正常屏幕(这些字符消失,屏幕空白。

切换到备用屏幕的终端功能是smcuprmcup。您可以使用不同(或修改)的终端描述。或者您可以告诉mintty不要切换到备用屏幕。根据它的manual page,它可以在设置对话框中执行此操作:

  

备用屏幕(NoAltScreen = false)   
  使用此设置,可以禁用备用屏幕。

手册指出这些设置对应于菜单条目,您可能会发现比编辑配置文件更简单:

  

Mintty还在窗口菜单中添加了几个项目,可以通过单击程序图标或按Alt + Space来访问它。

     

两个菜单都有一个条目,指向选项对话框,用于更改mintty的配置

答案 1 :(得分:-1)

ncurses通过三种方法获取窗口大小:

  • 在支持TIOCGWINSZ ioctl(2)的终端中,通过调用获取initscr(3)电话的窗口尺寸。
  • 通过terminfo数据库提供的信息。许多终端类型具有固定大小的维度,并且从该数据库获取行和列的适当值。
  • 获取LINES和COLUMNS环境变量的值。

好吧,bash(1)通常会调整这些环境变量值,以便在程序退出时和调用下一个程序之前更正,如果bash(1)可用,但是如果您的程序不支持SIGWINCH信号(或不处理它),很可能ncurses库不会知道程序运行期间窗口大小已经改变(默认情况下我还没有看到ncurses检测到这一点,无论如何)。即使在运行支持它的系统的情况下,如果您没有为该信号安装信号处理程序,ncurses库本身也无法承担窗口维度的变化,因为它必须调整stdscr内容的大小和可以使用几个标准来处理旧内容和新的自由空间。

我观察到的标准是ncurses本身不处理窗口更改(至少在默认情况下,你必须考虑这与ncurses发生的事情是一样的,它不检测另一个进程是否写入你的tty,屏幕出现乱码)。要处理这个问题,你必须为SIGWINCH信号安装一个信号处理程序(这个信号在发生终端尺寸变化时发送到整个过程组,通常来自pty主站),并使其成为合适的{t}设备ioctl(2)获取新窗口维度并调用适当的低级别ncurses例程来更改stdsrcstdwin缓冲区的新几何,因为需要重新分配内存他们。这意味着您可以自由决定终端调整大小时窗口内容会发生什么,但会让您完成所有工作来处理它。我有一个程序,SIGWINCH只需exec(2)自身并重新启动,因此它会在initscr(3)调用中获得新的屏幕尺寸。如果您无法自动exec(2)您的计划,只需深入了解如何重置stdscr维度以及正确更改LINSCOLS全局变量的文档。 (如果我找到有关如何操作的文档,我将使用适当的信息编辑此答案。)

我已经运行了你的程序,它按预期工作......用星号填充第一行和最后一行。只需在getch()之前拨打endwin()即可看到所绘制的屏幕。