tcapquery.pl revision e0a2b6df
1#!/usr/bin/env perl
2# $XTermId: tcapquery.pl,v 1.19 2014/02/26 20:15:12 tom Exp $
3# -----------------------------------------------------------------------------
4# this file is part of xterm
5#
6# Copyright 2004-2010,2014 by Thomas E. Dickey
7#
8#                         All Rights Reserved
9#
10# Permission is hereby granted, free of charge, to any person obtaining a
11# copy of this software and associated documentation files (the
12# "Software"), to deal in the Software without restriction, including
13# without limitation the rights to use, copy, modify, merge, publish,
14# distribute, sublicense, and/or sell copies of the Software, and to
15# permit persons to whom the Software is furnished to do so, subject to
16# the following conditions:
17#
18# The above copyright notice and this permission notice shall be included
19# in all copies or substantial portions of the Software.
20#
21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
25# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28#
29# Except as contained in this notice, the name(s) of the above copyright
30# holders shall not be used in advertising or otherwise to promote the
31# sale, use or other dealings in this Software without prior written
32# authorization.
33# -----------------------------------------------------------------------------
34# Test the tcap-query option of xterm.
35
36use strict;
37use warnings;
38
39use Getopt::Std;
40use IO::Handle;
41
42our ($opt_a, $opt_b, $opt_c, $opt_e, $opt_f, $opt_i, $opt_k, $opt_m, $opt_t, $opt_x, $opt_X);
43&getopts('abcefikmt:x:X') || die("Usage: $0 [options]\n
44Options:\n
45  -a      (same as -c -e -f -k -m)
46  -b      use both terminfo and termcap (default is termcap)
47  -c      cursor-keys
48  -e      editing keypad-keys
49  -f      function-keys
50  -i      use terminfo rather than termcap names
51  -k      numeric keypad-keys
52  -m      miscellaneous (none of -c, -e, -f, -k)
53  -t NAME use given NAME for \$TERM, set that in xterm's tcap keyboard
54  -x KEY  extended cursor/editing key (terminfo only)
55  -X      test all extended cursor- and/or editing-keys (terminfo)
56");
57
58if ( not ( defined($opt_c)
59	or defined($opt_e)
60	or defined($opt_f)
61	or defined($opt_k)
62	or defined($opt_m)
63	or defined($opt_x) ) ) {
64	$opt_a=1;
65}
66
67sub no_reply($) {
68	open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n");
69	autoflush TTY 1;
70	my $old=`stty -g`;
71	system "stty raw -echo min 0 time 5";
72
73	print TTY @_;
74	close TTY;
75	system "stty $old";
76}
77
78sub get_reply($) {
79	open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n");
80	autoflush TTY 1;
81	my $old=`stty -g`;
82	system "stty raw -echo min 0 time 5";
83
84	print TTY @_;
85	my $reply=<TTY>;
86	close TTY;
87	system "stty $old";
88	if ( defined $reply ) {
89		die("^C received\n") if ( "$reply" eq "\003" );
90	}
91	return $reply;
92}
93
94sub hexified($) {
95	my $value = $_[0];
96	my $result = "";
97	my $n;
98
99	for ( $n = 0; $n < length($value); ++$n) {
100		$result .= sprintf("%02X", ord substr($value,$n,1));
101	}
102	return $result;
103}
104
105sub modify_tcap($) {
106	my $name = $_[0];
107	my $param = hexified($name);
108	no_reply("\x1bP+p" . $param . "\x1b\\");
109}
110
111sub query_tcap($$) {
112	my $tcap = $_[0];
113	my $tinfo = $_[1];
114	my $param1 = hexified($tcap);
115	my $param2 = hexified($tinfo);
116	my $reply;
117
118	# uncomment one of the following lines
119	if ( defined($opt_b) ) {
120		$reply=get_reply("\x1bP+q" . $param1 . ";" . $param2 . "\x1b\\");
121	} elsif ( defined($opt_i) ) {
122		$reply=get_reply("\x1bP+q" . $param2 . "\x1b\\");
123	} else {
124		$reply=get_reply("\x1bP+q" . $param1 . "\x1b\\");
125	}
126
127	return unless defined $reply;
128	if ( $reply =~ /\x1bP1\+r[[:xdigit:]]+=[[:xdigit:]]*.*/ ) {
129		my $value = $reply;
130		my $n;
131
132		$value =~ s/^\x1bP1\+r//;
133		$value =~ s/\x1b\\//;
134
135		my $result = "";
136		for ( $n = 0; $n < length($value); ) {
137			my $c = substr($value,$n,1);
138			# handle semicolon and equals
139			if ( $c =~ /[[:punct:]]/ ) {
140				$n += 1;
141				$result .= $c;
142			} else {
143				# handle hex-data
144				my $k = hex substr($value,$n,2);
145				if ( $k == 0x1b ) {
146					$result .= "\\E";
147				} elsif ( $k == 0x7f ) {
148					$result .= "^?";
149				} elsif ( $k == 32 ) {
150					$result .= "\\s";
151				} elsif ( $k < 32 ) {
152					$result .= sprintf("^%c", $k + 64);
153				} elsif ( $k > 128 ) {
154					$result .= sprintf("\\%03o", $k);
155				} else {
156					$result .= chr($k);
157				}
158				$n += 2;
159			}
160		}
161
162		printf "%s\n", $result;
163	}
164}
165
166# extended-keys are a feature of ncurses 5.0 and later
167sub query_extended($) {
168	my $name = $_[0];
169	my $n;
170
171	$name = "k" . $name if ( $name !~ /^k/ );
172
173	for ( $n = 2; $n <= 7; ++$n) {
174		my $test = $name;
175		$test = $test . $n if ( $n > 2 );
176		query_tcap( $name, $test );
177	}
178}
179
180query_tcap(	"TN",	"name");
181if ( defined($opt_t) ) {
182	printf "Setting TERM=%s\n", $opt_t;
183	modify_tcap($opt_t);
184}
185
186# See xtermcapKeycode()
187if ( defined($opt_a) || defined($opt_c) ) {
188query_tcap(	"ku",	"kcuu1");
189query_tcap(	"kd",	"kcud1");
190query_tcap(	"kr",	"kcuf1");
191query_tcap(	"kl",	"kcub1");
192
193query_tcap(	"kF",	"kind");
194query_tcap(	"kR",	"kri");
195query_tcap(	"%i",	"kRIT");
196query_tcap(	"#4",	"kLFT");
197}
198
199if ( defined($opt_a) || defined($opt_e) ) {
200query_tcap(	"kD",	"kdch1");
201query_tcap(	"kI",	"kich1");
202
203query_tcap(	"kh",	"khome");
204query_tcap(	"\@7",	"kend");
205query_tcap(	"#2",	"kHOM");
206query_tcap(	"*7",	"kEND");
207
208query_tcap(	"*6",	"kslt");
209query_tcap(	"#6",	"kSLT");
210query_tcap(	"\@0",	"kfnd");
211query_tcap(	"*0",	"kFND");
212
213query_tcap(	"kN",	"knp");
214query_tcap(	"kP",	"kpp");
215
216query_tcap(	"%c",	"kNXT");
217query_tcap(	"%e",	"kPRV");
218}
219
220if ( defined($opt_a) || defined($opt_f) ) {
221query_tcap(	"k1",	"kf1");
222query_tcap(	"k2",	"kf2");
223query_tcap(	"k3",	"kf3");
224query_tcap(	"k4",	"kf4");
225query_tcap(	"k5",	"kf5");
226query_tcap(	"k6",	"kf6");
227query_tcap(	"k7",	"kf7");
228query_tcap(	"k8",	"kf8");
229query_tcap(	"k9",	"kf9");
230query_tcap(	"k;",	"kf10");
231query_tcap(	"F1",	"kf11");
232query_tcap(	"F2",	"kf12");
233query_tcap(	"F3",	"kf13");
234query_tcap(	"F4",	"kf14");
235query_tcap(	"F5",	"kf15");
236query_tcap(	"F6",	"kf16");
237query_tcap(	"F7",	"kf17");
238query_tcap(	"F8",	"kf18");
239query_tcap(	"F9",	"kf19");
240query_tcap(	"FA",	"kf20");
241query_tcap(	"FB",	"kf21");
242query_tcap(	"FC",	"kf22");
243query_tcap(	"FD",	"kf23");
244query_tcap(	"FE",	"kf24");
245query_tcap(	"FF",	"kf25");
246query_tcap(	"FG",	"kf26");
247query_tcap(	"FH",	"kf27");
248query_tcap(	"FI",	"kf28");
249query_tcap(	"FJ",	"kf29");
250query_tcap(	"FK",	"kf30");
251query_tcap(	"FL",	"kf31");
252query_tcap(	"FM",	"kf32");
253query_tcap(	"FN",	"kf33");
254query_tcap(	"FO",	"kf34");
255query_tcap(	"FP",	"kf35");
256query_tcap(	"FQ",	"kf36");
257query_tcap(	"FR",	"kf37");
258query_tcap(	"FS",	"kf38");
259query_tcap(	"FT",	"kf39");
260query_tcap(	"FU",	"kf40");
261query_tcap(	"FV",	"kf41");
262query_tcap(	"FW",	"kf42");
263query_tcap(	"FX",	"kf43");
264query_tcap(	"FY",	"kf44");
265query_tcap(	"FZ",	"kf45");
266query_tcap(	"Fa",	"kf46");
267query_tcap(	"Fb",	"kf47");
268query_tcap(	"Fc",	"kf48");
269query_tcap(	"Fd",	"kf49");
270query_tcap(	"Fe",	"kf50");
271query_tcap(	"Ff",	"kf51");
272query_tcap(	"Fg",	"kf52");
273query_tcap(	"Fh",	"kf53");
274query_tcap(	"Fi",	"kf54");
275query_tcap(	"Fj",	"kf55");
276query_tcap(	"Fk",	"kf56");
277query_tcap(	"Fl",	"kf57");
278query_tcap(	"Fm",	"kf58");
279query_tcap(	"Fn",	"kf59");
280query_tcap(	"Fo",	"kf60");
281query_tcap(	"Fp",	"kf61");
282query_tcap(	"Fq",	"kf62");
283query_tcap(	"Fr",	"kf63");
284}
285
286if ( defined($opt_a) || defined($opt_k) ) {
287query_tcap(	"K1",	"ka1");
288query_tcap(	"K3",	"ka3");
289query_tcap(	"K4",	"kc1");
290query_tcap(	"K5",	"kc3");
291}
292
293if ( defined($opt_a) || defined($opt_m) ) {
294query_tcap(	"kB",	"kcbt");
295query_tcap(	"kC",	"kclr");
296query_tcap(	"&8",	"kund");
297
298query_tcap(	"kb",	"kbs");
299
300query_tcap(	"%1",	"khlp");
301query_tcap(	"#1",	"kHLP");
302
303query_tcap(	"Co",	"colors");
304}
305
306if ( defined ($opt_x) ) {
307	query_extended($opt_x);
308}
309
310if ( defined ($opt_X) ) {
311	if ( defined($opt_c) ) {
312		query_extended("DN");
313		query_extended("UP");
314		query_extended("LFT");
315		query_extended("RIT");
316	}
317	if ( defined($opt_e) ) {
318		query_extended("DC");
319		query_extended("END");
320		query_extended("HOM");
321		query_extended("IC");
322		query_extended("NXT");
323		query_extended("PRV");
324	}
325}
326