【问题标题】:how to add persistence to ncurses?如何为ncurses添加持久性?
【发布时间】:2013-06-28 02:52:20
【问题描述】:

问题

我想为 ncurses 程序添加持久性:在退出时将最后显示的屏幕写入磁盘,在进入时从磁盘读取最后显示的屏幕。如果可能,请包括背景色和前景色。

问题

  1. 有没有办法从出现在 NWindow 或 NPanel 中的 ncurses 中读取整个文本块,或者我是否必须维护自己的缓冲区并基本上写入/读取两次(到我的缓冲区和 ncurses)?
  2. 关于 COLOR_PAIR 信息的相同问题。

回答

Rici's answer below 是完美的,但我必须进行一些试验才能获得正确的呼叫顺序。

用法

下面的代码实际上非常适合保存和恢复颜色。

  • 不带参数运行一次以写出屏幕转储文件/tmp/scr.dump
  • 使用参数read 再次运行它以从文件中读取。

代码

#include <ncurses.h>
#include <string.h>

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string);
int main(int argc, char *argv[])
{

   bool read_mode = ( argc>1 && !strcmp( argv[1], "read" ));

   initscr();          /* Start curses mode        */

   if(has_colors() == FALSE)
   {
       endwin();
       printf("Your terminal does not support color\n");
       return 1;
   }
   start_color();              /* Start color          */
   use_default_colors();   // allow for -1 to mean default color
   init_pair(1, COLOR_RED, -1);

   if ( read_mode )
   {
       refresh();
       if ( scr_restore( "/tmp/scr.dump" )!=OK )
       {
           fprintf( stderr, "ERROR DURING RESTORE\n" );
           return 1;
       }
       doupdate();

       attron(COLOR_PAIR(1));
       print_in_middle(stdscr, LINES / 2 + 9, 0, 0, "Read from /tmp/scr.dump" );
       attroff(COLOR_PAIR(1));
   } else {
       attron(COLOR_PAIR(1));
       print_in_middle(stdscr, LINES / 2, 0, 0, "Viola !!! In color ...");
       attroff(COLOR_PAIR(1));

       if ( scr_dump( "/tmp/scr.dump" )!=OK )
       {
           fprintf( stderr, "ERROR WHILE DUMPING" );
           return 1;
       }
   }

  getch();
   endwin();
}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string)
{  int length, x, y;
   float temp;

   if(win == NULL)
       win = stdscr;
   getyx(win, y, x);
   if(startx != 0)
       x = startx;
   if(starty != 0)
       y = starty;
   if(width == 0)
       width = 80;

   length = strlen(string);
   temp = (width - length)/ 2;
   x = startx + (int)temp;
   mvwprintw(win, y, x, "%s", string);
   refresh();
}

【问题讨论】:

  • 为什么不只存储足够的空间来根据您的应用逻辑重建屏幕?
  • @crowder 我确实在我的 OP 中提到了这一点(在 Q1 下)。如果可能的话,我会尽量避免它(毕竟,ncurses 已经将所有这些信息存储在内存中的某个地方!)另请注意,存储我自己的缓冲区本质上是对 ncurses 前端的重写,而无需实际写入屏幕。
  • 当然可以,但是您必须存储的信息量可能要少得多,无论如何,您必须重建一些上下文来确定您的应用在恢复时处于什么状态。例如,一个“less”风格的应用程序只需要存储一个文件偏移量。更好的是,您的自定义存储信息不会因屏幕尺寸变化而失效,就像 ncurses “状态”那样。
  • @crowder 我尝试编写尽可能少的新代码,因为我对错误过敏 - 但是 nm,看起来下面的 rici 有一个很好的解决方案...

标签: c++ c c++11 ncurses


【解决方案1】:

man scr_dump:

   scr_dump, scr_restore, scr_init, scr_set -
       read (write) a curses screen from (to) a file

【讨论】:

  • 这个解决方案是完美的——我已经为其他可能觉得有用的人添加了代码到 OP 中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2019-06-02
  • 1970-01-01
  • 2011-04-21
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多