微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当我调整窗口大小时,Termcaps 的行和列不会改变

如何解决当我调整窗口大小时,Termcaps 的行和列不会改变

我正在尝试获取终端窗口大小,即使我调整窗口大小,我为此使用了 termcaps,问题是当我调整窗口大小时,行和列的值保持不变而不是更新,我也尝试使用 ncurses 的 LInes 和 COLS 全局变量,但同样的事情发生了。 这是一个最小的可重现示例:

#include <ncurses.h>
#include <term.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    char * term_type = getenv("TERM");
    int ret;
    int li_cap;
    int co_cap;

    if (!term_type)
    {
        write(2,"TERM env must be set\n",21);
        return (-1);
    }
    if ((ret = tgetent(NULL,term_type)) == -1)
    {
        write(2,"Could not access to the termcap database\n",41);
        return (-1);
    }
    if (!ret)
    {
        write(2,"This terminal is not supported by termcaps\n",43);
        return (-1);
    }
    while (1)
    {
        sleep(1);
        li_cap = tgetnum("li");
        co_cap = tgetnum("co");
        printf("%d %d\n",li_cap,co_cap);
    }
    return (0);
}

所以当我在循环内调整窗口大小时,值保持不变,我想实时获取行和列,我怎么能用 termcaps 做到这一点?

解决方法

termcap 数据以及环境变量 COLUMNSLINES 不可靠,并且不会在终端调整大小时更新,尤其是在程序执行期间。对于 POSIX 系统,您可以使用另一种解决方案:

  • 使用 ioctl(0,TIOCGWINSZ,&ws) 检索终端窗口的大小
  • 注册一个信号处理程序以获得终端大小变化的通知。

这是一个演示程序:

#include <stdio.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>

static volatile unsigned char term_size_updated;

static void term_resize() {
    term_size_updated = 1;
}

static void term_get_size(int *cols,int *rows) {
    struct winsize ws;

    /* get screen dimensions from (pseudo) tty ioctl */
    if (ioctl(0,&ws) == 0) {
        *cols = ws.ws_col;
        *rows = ws.ws_row;
    } else {
        *cols = *rows = -1;
    }
}

int main() {
    struct sigaction sig;
    int cols,rows;

    /* set up terminal resize callback */
    sig.sa_handler = term_resize;
    sigemptyset(&sig.sa_mask);
    sig.sa_flags = 0;
    sigaction(SIGWINCH,&sig,NULL);

    term_size_updated = 1;
    for (;;) {
        if (term_size_updated) {
            term_size_updated = 0;
            term_get_size(&cols,&rows);
            fprintf(stderr,"term_resize: cols=%d,rows=%d\n",cols,rows);
        }
        sleep(1);
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。