`

终端窗口大小和 termcap

阅读更多
    多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的方法。在窗口大小发生变化时,内核就会通知前台进程组。内核为每个终端和伪终端都维护了一个如下的 winsize 结构。
struct winsize{
    unsigned short ws_row;        // rows, in characters
    unsigned short ws_col;        // columns, in characters
    unsigned short ws_xpixel;     // horizontal size, pixels (unused)
    unsigned short ws_ypixel;     // vertical size, pixels (unused)
};

    此结构的规则如下:
    1、用 ioctl 函数(见终端I/O函数 ioctl一节)的 TIOCGWINSZ 命令可以取此结构的当前值。
    2、用 ioctl 的 TIOCSWINSZ 命令可以将此结构的新值存储到内核中。如果此新值与存储在内核中的当前值不同,则将向前台进程组发送 SIGWINCH 信号(默认会被忽略)。
    3、除了存储此结构的当前值以及在此值改变时产生一个信号以外,内核对该结构不进行任何其他操作。对结构中的值进行解释是应用程序的工作。
    提供这种功能的目的是,当窗口大小发生变化时应用程序能得到通知(如 vi 编辑器)。应用程序接收到此信号后,可以获取窗口大小的新值,然后重绘屏幕。
    下面这个程序会打印当前窗口大小,然后休眠。之后每次窗口大小改变时,程序就捕捉 SIGWINCH 信号,然后打印新的窗口大小。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif

static void pr_winsize(int fd){
	struct winsize	size;
	if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0){
		printf("TIOCGWINSZ error\n");
		exit(1);
	}
	printf("%d rows, %d columns\n", size.ws_row, size.ws_col);
}

static void sig_winch(int signo){
	printf("SIGWINCH received\n");
	pr_winsize(STDIN_FILENO);
}

int main(void){
	if(isatty(STDIN_FILENO) == 0)
		exit(1);
	if(signal(SIGWINCH, sig_winch) == SIG_ERR){
		printf("signal error\n");
		exit(1);
	}
	pr_winsize(STDIN_FILENO);		// print initial size
	for(;;)					// and sleep forever
		pause();
}


    termcap 的意思是终端能力(terminal capability),它涉及文本文件 /etc/termcap 和一套读此文件的例程,主要是为了支持 vi 编辑器而开发的。termcap 文件包含了对各种终端的说明:终端支持哪些功能(如行数、列数、是否支持退格)、如何使终端执行某些操作(如清屏、移动光标到指定位置)等。把这些信息从编译过的程序中取出来并把它们放在易于编辑的文本文件中,这样就使得 vi 编辑器能在很多不同的终端上运行。最后,将支持 termcap 文件的例程从 vi 编辑器中抽取出来,放在一个单独的 curses 库中。为使这套库可供要进行屏幕处理的任何程序使用,还增加了很多功能。
    不过 termcap 这种技术并不是很完善。因为当越来越多的终端被加到数据文件中时,为找到一个特定的终端,可能需要花费很长的时间扫描此数据文件。另外,该数据文件还用两个字符的名字来标识不同的终端属性。因此出现了 terminfo 以及与其相关的 curses 库。在 terminfo 中,终端说明基本上都是文本说明的编译版本,在运行时易于被快速定位。
    但不论是 termcap 还是 terminfo,它们本身都只提供在各种终端上执行典型操作(如清屏、移动光标等)的方法,而不处理如更改终端模式、更改终端特殊字符、处理窗口大小等问题。不过 curses 库能提供某种具体细节方面的帮助。它提供了很多函数,用来设置原始模式、设置 cbreak 模式、打开和关闭回显等。注意,curses 库是为基于字符的哑终端设计的,它们如今大部分已被基于像素的图像终端所代替。
  • 大小: 11.5 KB
分享到:
评论

相关推荐

    linux下使用curses库实现滚屏、彩色打印等个性化屏幕输出

    通过`mvwin()`可以移动窗口,`resize_win()`调整大小,`subwin()`和`derwin()`创建子窗口。`wnoutrefresh()`和`wrefresh()`用于更新窗口到屏幕。 【视窗卷动】`wmove()`移动窗口内的光标,`wscroll()`用于滚动窗口...

    Oracle Solaris 11.1 man pages section3:Curses Library Functions

    `subwin()` 和 `derwin()` 用于从已有窗口创建子窗口,`mvwin()` 可以改变窗口的位置,`resize_term()` 和 `resize_window()` 用于调整终端或窗口的大小。 3. **颜色管理**:Curses 提供了颜色支持,`init_pair()` ...

    UNIX环境高级编程_第二版中文

    18.12 终端的窗口大小  18.13 termcap,terminfo和curses  18.14 小结  习题  第19章 伪终端  19.1 引言  19.2 概述  19.3 打开伪终端设备  19.3.1 基于STREAMS的伪终端  19.3.2 基于BSD的伪终端...

    UNIX环境高级编程

    11.12 终端的窗口大小 11.13 termcap, terminfo和 curses 11.14 小结 习题 第12章 高级I/O 12.1 引言 12.2 非阻塞I/O 12.3 记录锁 12.3.1 历史 12.3.2 fcntl记录锁 12.3.3 锁的隐含继承和释放 12.3.4 4.3+BSD的实现...

    UNIX环境高级编程和源代码

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX高级编程 计算机科学丛书

    11.12 终端的窗口大小 11.13 termcap, terminfo和 curses 11.14 小结 习题 第12章 高级I/O 12.1 引言 12.2 非阻塞I/O 12.3 记录锁 12.3.1 历史 12.3.2 fcntl记录锁 12.3.3 锁的隐含继承和释放 12.3.4 4.3+BSD的实现...

    UNIX环境高级编程 pdf格式

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.4 流 288 12.5 I/O多路转接 296 12.6 异步I/O ...

    IT行业中必备技能之UNIX最佳学习资料

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    Unix高级编程 pdf

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 ...

    UNIX环境高级编程(PDF)

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX环境高级编程(中文版+英文版+源代码)

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX环境高级编程.pdf

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    Unix环境高级编程电子书

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    中文第一版-UNIX环境高级编程

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX环境高级编程(第二版中文)

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX环境高级编程(第二版中文).

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX环境高级编程(第二版中文).pdf

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

    UNIX环境高级编程第二版

    11.12 终端的窗口大小 270 11.13 termcap, terminfo和 curses 271 11.14 小结 272 习题 272 第12章 高级I/O 273 12.1 引言 273 12.2 非阻塞I/O 273 12.3 记录锁 275 12.3.1 历史 276 12.3.2 fcntl记录锁 276 12.3.3 ...

Global site tag (gtag.js) - Google Analytics