我正在编写CLI服务器。在我的项目中,我做了以下(简化):
curses.setupterm("rxvt")
smkx = curses.tigetstr("smkx")
write_to_terminal_client(smkx)
检测到的smkx序列仅为" \ E ="它匹配" infocmp rxvt" (一个糟糕的terminfo条目?)。
现在,当我运行CLI服务器并通过在rxvt终端上运行telnet连接到它时,终端接收smkx序列。 当rxvt终端上的用户按下左箭头键时,我会指望" \ E [D"序列将被发送到CLI服务器(因为已设置应用程序模式)。不幸的是,序列总是" \ EOD"当smkx序列有和没有被发送到终端客户端时。
我尝试将smkx序列硬编码为" \ E [?1h \ E ="并将其发送给客户,但它没有改变任何东西。
终端也不响应DECRQM查询。
我的全貌是,我的应用程序了解终端的名称,并在terminfo数据库中查询密钥代码和其他功能。 我正在运行ubuntu 13.10。 Rxvt终端是" 2.7.10"
问题:
此致
答案 0 :(得分:1)
问题似乎是你的程序正在发送smkx
(好),但假设它知道将为各种特殊键发送的字符串(不好)。在正确构造的终端描述中,还列出了特殊键(参见terminfo(5)):
key_up kcuu1 ku up-arrow key key_down kcud1 kd down-arrow key key_left kcub1 kl left-arrow key key_right kcuf1 kr right-arrow key
因此,您的计划应该寻找\E[D
所说的tigetstr
的字符串,而不是寻找kcub1
。
关于DECRQM
,rxvt可能无法实现,因为它不是“VT100”控制序列。参考 XTerm Control Sequences ,即“For VT300 and up”,而rxvt's manual页面则显示“vt102 terminal”。
虽然报告偶尔会出现问题,但终端数据库很大程度上反映了用户惯例与实际终端功能之间的权衡。某些用户(特别是bash
的Linux用户)不喜欢使用终端的应用程序模式。在这个利基之外,长期以来的惯例是使用应用程序模式。 xterm manual提供了有关此主题的其他讨论。
在ncurses中,infocmp
命令具有一个功能(选项-i
),可以让您更清楚地看到初始化字符串的效果。它不会分解rmkx / smkx,但这很容易添加。这样做,它会报告rxvt:
is1: {DEC-47}{DECPAM}{DEC-CKM}
is2: {RSR}{SGR0}\E[2J{home}{DEC+AWM}{DEC-CKM;COLM;SCLM;OM}{rmir}
rs1: {rmkx}{ECMA-1;3;IRM;5;6}{DEC+AWM}{SGR0}{RSR}\E[2J{home}
rs2: {is2}{rmkx}{DEC-1000}{cnorm}
smcup: {sc}{DEC+47}
rmcup: \E[2J{DEC-47}{rc}
smkx: {DECPAM}
rmkx: {DECPNM}
和xterm:
is2: \E[!p{DEC-COLM;SCLM}{rmir}{DECPNM}
rs1: {RIS}
rs2: {is2}
smcup: {DEC+1049}
rmcup: {DEC-1049}
smkx: {DEC+CKM}{DECPAM}
rmkx: {DEC-CKM}{DECPNM}
也就是说,xterm的终端描述使用smkx / rmkx打开/关闭DECCKM
(光标键),而rxvt的终端描述则不然。另外,rxvt的初始化字符串会关闭DECCKM
。