在终端中实施叠加 [英] Implement overlay in terminal

查看:146
本文介绍了在终端中实施叠加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在终端中创建一个叠加层

I want to create an overlay in terminal

此Q& D在右/下显示时间

This Q&D shows the time in right/bottom

#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <termios.h>
#include <error.h>
#include <unistd.h>
#include <time.h>

static char termbuf[2048];

int main()
{
   char *termtype = getenv("TERM");

   time_t timer;
   char buffer[26];
   struct tm* tm_info;

   if (tgetent(termbuf, termtype) < 0) {
      error(EXIT_FAILURE, 0, "Could not access the termcap data base.\n");
      return 1;
   }

   int lines = tgetnum("li");
   int columns = tgetnum("co");
   int pos=1;
   while (1) {
      time(&timer);
      tm_info = localtime(&timer);
      strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
      printf("\033[s");
      fflush(stdout);

      printf("\033[%d;%dH%s\n", lines - 2, columns - 20, buffer);
      printf("\033[u");
      sleep(1);
   }
   return 0;
}

使用以下命令进行编译:

it is compiled with:

$ gcc time-overlay.c -ltermcap -o time-overlay

并使用它:

$ ./time-overlay &

它将显示:

                                                    2017-04-29 12:29:15

并保持更新时间.

要停止:

$ fg
Ctrl+C

但是,有没有更好的方法来使用一些抽象底层调用的库(例如保存恢复光标位置或以某些行/列打印)

But, is there a better way to do that with some library that abstracts low level calls (like save restore cursor position or print in some line/col)

我想保留现有的终端输出(因此使用initscr()进行诅咒将不起作用)

I want to keep existing terminal output (so curses with initscr() will not work)

推荐答案

这是您使用termcap的方式(或任何提供termcap 接口(例如ncurses)的方式):

This is how you would use termcap (or anything provides a termcap interface, e.g., ncurses):

#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

#define MAXTERM 2048
#define EndOf(s) (s) + strlen(s)

int
main(void)
{
    char termbuf[MAXTERM];
    char workbuf[MAXTERM];
    char *working = workbuf;

    int lines, columns;
    char *save_cursor, *move_cursor, *restore_cursor;

    if (tgetent(termbuf, getenv("TERM")) < 0) {
        fprintf(stderr, "Could not access the termcap database.\n");
        return EXIT_FAILURE;
    }

    lines = tgetnum("li");
    columns = tgetnum("co");
    save_cursor = tgetstr("sc", &working);
    move_cursor = tgetstr("cm", &working);
    restore_cursor = tgetstr("rc", &working);

    while (1) {
        time_t timer;
        char buffer[1024];
        struct tm *tm_info;

        time(&timer);
        tm_info = localtime(&timer);

        strcpy(buffer, save_cursor);
        sprintf(EndOf(buffer), tgoto(move_cursor, columns - 20, lines - 2));
        strftime(EndOf(buffer), 26, "%Y-%m-%d %H:%M:%S", tm_info);
        strcat(buffer, restore_cursor);

        write(fileno(stderr), buffer, strlen(buffer));
        sleep(1);
    }
    return EXIT_SUCCESS;
}

由于所有终端描述都没有保证提供从tgetstr返回的各种字符串,因此仍可以改进,当然,termcap应用程序始终存在缓冲区溢出问题来解决

It could still be improved since the various strings returned from tgetstr are not guaranteed to be provided by all terminal descriptions, and of course, termcap applications always have buffer-overflow issues to work around.

这篇关于在终端中实施叠加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆