1e0a2b6dfSmrg#!/usr/bin/env perl 204b94745Smrg# $XTermId: tcapquery.pl,v 1.29 2019/04/29 23:27:57 tom Exp $ 320d2c4d2Smrg# ----------------------------------------------------------------------------- 420d2c4d2Smrg# this file is part of xterm 5d522f475Smrg# 6f2e35a3aSmrg# Copyright 2004-2018,2019 by Thomas E. Dickey 7913cc679Smrg# 820d2c4d2Smrg# All Rights Reserved 9913cc679Smrg# 1020d2c4d2Smrg# Permission is hereby granted, free of charge, to any person obtaining a 1120d2c4d2Smrg# copy of this software and associated documentation files (the 1220d2c4d2Smrg# "Software"), to deal in the Software without restriction, including 1320d2c4d2Smrg# without limitation the rights to use, copy, modify, merge, publish, 1420d2c4d2Smrg# distribute, sublicense, and/or sell copies of the Software, and to 1520d2c4d2Smrg# permit persons to whom the Software is furnished to do so, subject to 1620d2c4d2Smrg# the following conditions: 17913cc679Smrg# 1820d2c4d2Smrg# The above copyright notice and this permission notice shall be included 1920d2c4d2Smrg# in all copies or substantial portions of the Software. 20913cc679Smrg# 2120d2c4d2Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2220d2c4d2Smrg# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2320d2c4d2Smrg# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 2420d2c4d2Smrg# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 2520d2c4d2Smrg# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2620d2c4d2Smrg# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2720d2c4d2Smrg# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28913cc679Smrg# 2920d2c4d2Smrg# Except as contained in this notice, the name(s) of the above copyright 3020d2c4d2Smrg# holders shall not be used in advertising or otherwise to promote the 3120d2c4d2Smrg# sale, use or other dealings in this Software without prior written 3220d2c4d2Smrg# authorization. 3320d2c4d2Smrg# ----------------------------------------------------------------------------- 34d522f475Smrg# Test the tcap-query option of xterm. 35d522f475Smrg 36d522f475Smrguse strict; 37e0a2b6dfSmrguse warnings; 38d522f475Smrg 39d522f475Smrguse Getopt::Std; 40d522f475Smrguse IO::Handle; 41d522f475Smrg 42913cc679Smrgour ( 43913cc679Smrg $opt_a, $opt_b, $opt_c, $opt_e, $opt_f, $opt_i, 44f2e35a3aSmrg $opt_k, $opt_m, $opt_q, $opt_t, $opt_x, $opt_X 45913cc679Smrg); 46f2e35a3aSmrg 47f2e35a3aSmrgour @query_params; 48f2e35a3aSmrgour @query_result; 49f2e35a3aSmrg 50f2e35a3aSmrg$Getopt::Std::STANDARD_HELP_VERSION = 1; 51f2e35a3aSmrg&getopts('abcefikmqt:x:X') || die( 52913cc679Smrg "Usage: $0 [options]\n 53d522f475SmrgOptions:\n 5420d2c4d2Smrg -a (same as -c -e -f -k -m) 5520d2c4d2Smrg -b use both terminfo and termcap (default is termcap) 5620d2c4d2Smrg -c cursor-keys 5720d2c4d2Smrg -e editing keypad-keys 5820d2c4d2Smrg -f function-keys 5920d2c4d2Smrg -i use terminfo rather than termcap names 6020d2c4d2Smrg -k numeric keypad-keys 6120d2c4d2Smrg -m miscellaneous (none of -c, -e, -f, -k) 62f2e35a3aSmrg -q quicker results by merging queries 6320d2c4d2Smrg -t NAME use given NAME for \$TERM, set that in xterm's tcap keyboard 6420d2c4d2Smrg -x KEY extended cursor/editing key (terminfo only) 6520d2c4d2Smrg -X test all extended cursor- and/or editing-keys (terminfo) 66913cc679Smrg" 67913cc679Smrg); 68913cc679Smrg 69913cc679Smrgif ( 70913cc679Smrg not( defined($opt_c) 71913cc679Smrg or defined($opt_e) 72913cc679Smrg or defined($opt_f) 73913cc679Smrg or defined($opt_k) 74913cc679Smrg or defined($opt_m) 75913cc679Smrg or defined($opt_x) ) 76913cc679Smrg ) 77913cc679Smrg{ 78913cc679Smrg $opt_a = 1; 79d522f475Smrg} 80d522f475Smrg 8120d2c4d2Smrgsub no_reply($) { 82913cc679Smrg open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n"); 83913cc679Smrg autoflush TTY 1; 84913cc679Smrg my $old = `stty -g`; 85913cc679Smrg system "stty raw -echo min 0 time 5"; 86913cc679Smrg 87913cc679Smrg print TTY @_; 88913cc679Smrg close TTY; 89913cc679Smrg system "stty $old"; 9020d2c4d2Smrg} 9120d2c4d2Smrg 92d522f475Smrgsub get_reply($) { 93913cc679Smrg open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n"); 94913cc679Smrg autoflush TTY 1; 95913cc679Smrg my $old = `stty -g`; 96913cc679Smrg system "stty raw -echo min 0 time 5"; 97913cc679Smrg 98913cc679Smrg print TTY @_; 99913cc679Smrg my $reply = <TTY>; 100913cc679Smrg close TTY; 101913cc679Smrg system "stty $old"; 102913cc679Smrg if ( defined $reply ) { 103913cc679Smrg die("^C received\n") if ( "$reply" eq "\003" ); 104913cc679Smrg } 105913cc679Smrg return $reply; 106d522f475Smrg} 107d522f475Smrg 108d522f475Smrgsub hexified($) { 109913cc679Smrg my $value = $_[0]; 110913cc679Smrg my $result = ""; 111913cc679Smrg my $n; 112913cc679Smrg 113913cc679Smrg for ( $n = 0 ; $n < length($value) ; ++$n ) { 114913cc679Smrg $result .= sprintf( "%02X", ord substr( $value, $n, 1 ) ); 115913cc679Smrg } 116913cc679Smrg return $result; 117d522f475Smrg} 118d522f475Smrg 11920d2c4d2Smrgsub modify_tcap($) { 120913cc679Smrg my $name = $_[0]; 121f2e35a3aSmrg my $param = &hexified($name); 122f2e35a3aSmrg &no_reply( "\x1bP+p" . $param . "\x1b\\" ); 12320d2c4d2Smrg} 12420d2c4d2Smrg 125f2e35a3aSmrgsub begin_query() { 126f2e35a3aSmrg @query_params = (); 127f2e35a3aSmrg} 128f2e35a3aSmrg 129f2e35a3aSmrgsub add_param($) { 130f2e35a3aSmrg $query_params[ $#query_params + 1 ] = &hexified( $_[0] ); 131f2e35a3aSmrg} 132f2e35a3aSmrg 133f2e35a3aSmrgsub finish_query() { 134f2e35a3aSmrg my $reply = &get_reply( "\x1bP+q" . join( ';', @query_params ) . "\x1b\\" ); 135913cc679Smrg 136913cc679Smrg return unless defined $reply; 137913cc679Smrg if ( $reply =~ /\x1bP1\+r[[:xdigit:]]+=[[:xdigit:]]*.*/ ) { 138913cc679Smrg my $n; 139913cc679Smrg 140f2e35a3aSmrg $reply =~ s/^\x1bP1\+r//; 141f2e35a3aSmrg $reply =~ s/\x1b\\//; 142913cc679Smrg 143913cc679Smrg my $result = ""; 144f2e35a3aSmrg my $count = 0; 145f2e35a3aSmrg my $state = 0; 146f2e35a3aSmrg my $error = "?"; 147f2e35a3aSmrg for ( $n = 0 ; $n < length($reply) ; ) { 148f2e35a3aSmrg my $c = substr( $reply, $n, 1 ); 149913cc679Smrg 150f2e35a3aSmrg if ( $c eq ';' ) { 151f2e35a3aSmrg $n += 1; 152f2e35a3aSmrg printf "%d%s\t%s\n", $count, $error, $result 153f2e35a3aSmrg if ( $result ne "" ); 154f2e35a3aSmrg $result = ""; 155f2e35a3aSmrg $state = 0; 156f2e35a3aSmrg $error = "?"; 157f2e35a3aSmrg $count++; 158f2e35a3aSmrg } 159f2e35a3aSmrg elsif ( $c eq '=' ) { 160f2e35a3aSmrg $error = "" 161f2e35a3aSmrg if ( $count <= $#query_params 162f2e35a3aSmrg and &hexified($result) eq $query_params[$count] ); 163f2e35a3aSmrg $n += 1; 164f2e35a3aSmrg $result .= $c; 165f2e35a3aSmrg $state = 1; 166f2e35a3aSmrg } 167f2e35a3aSmrg elsif ( $c =~ /[[:punct:]]/ ) { 168913cc679Smrg $n += 1; 169913cc679Smrg $result .= $c; 170913cc679Smrg } 171913cc679Smrg else { 172f2e35a3aSmrg my $k = hex substr( $reply, $n, 2 ); 173913cc679Smrg if ( $k == 0x1b ) { 174913cc679Smrg $result .= "\\E"; 175913cc679Smrg } 176913cc679Smrg elsif ( $k == 0x7f ) { 177913cc679Smrg $result .= "^?"; 178913cc679Smrg } 179913cc679Smrg elsif ( $k == 32 ) { 180913cc679Smrg $result .= "\\s"; 181913cc679Smrg } 182913cc679Smrg elsif ( $k < 32 ) { 183913cc679Smrg $result .= sprintf( "^%c", $k + 64 ); 184913cc679Smrg } 185913cc679Smrg elsif ( $k > 128 ) { 186913cc679Smrg $result .= sprintf( "\\%03o", $k ); 187913cc679Smrg } 188913cc679Smrg else { 189913cc679Smrg $result .= chr($k); 190913cc679Smrg } 191913cc679Smrg $n += 2; 192913cc679Smrg } 193913cc679Smrg } 194f2e35a3aSmrg printf "%d%s\t%s\n", $count, $error, $result if ( $result ne "" ); 195913cc679Smrg } 196d522f475Smrg} 197d522f475Smrg 198f2e35a3aSmrgsub query_tcap($$) { 199f2e35a3aSmrg my $tcap = shift; 200f2e35a3aSmrg my $tinfo = shift; 201f2e35a3aSmrg 202f2e35a3aSmrg &begin_query unless ($opt_q); 203f2e35a3aSmrg &add_param($tcap) if ( $opt_b or not $opt_i ); 204f2e35a3aSmrg &add_param($tinfo) if ( $opt_b or $opt_i ); 205f2e35a3aSmrg &finish_query unless ($opt_q); 206f2e35a3aSmrg} 207f2e35a3aSmrg 20820d2c4d2Smrg# extended-keys are a feature of ncurses 5.0 and later 209d522f475Smrgsub query_extended($) { 210913cc679Smrg my $name = $_[0]; 211913cc679Smrg my $n; 212d522f475Smrg 213913cc679Smrg $name = "k" . $name if ( $name !~ /^k/ ); 214d522f475Smrg 215913cc679Smrg for ( $n = 2 ; $n <= 7 ; ++$n ) { 216913cc679Smrg my $test = $name; 217913cc679Smrg $test = $test . $n if ( $n > 2 ); 218f2e35a3aSmrg &query_tcap( $name, $test ); 219913cc679Smrg } 220d522f475Smrg} 221d522f475Smrg 222f2e35a3aSmrg&begin_query if ($opt_q); 223f2e35a3aSmrg 224f2e35a3aSmrg&query_tcap( "TN", "name" ); 22520d2c4d2Smrgif ( defined($opt_t) ) { 226913cc679Smrg printf "Setting TERM=%s\n", $opt_t; 227f2e35a3aSmrg &modify_tcap($opt_t); 22820d2c4d2Smrg} 22920d2c4d2Smrg 230d522f475Smrg# See xtermcapKeycode() 231d522f475Smrgif ( defined($opt_a) || defined($opt_c) ) { 232f2e35a3aSmrg &query_tcap( "ku", "kcuu1" ); 233f2e35a3aSmrg &query_tcap( "kd", "kcud1" ); 234f2e35a3aSmrg &query_tcap( "kr", "kcuf1" ); 235f2e35a3aSmrg &query_tcap( "kl", "kcub1" ); 236f2e35a3aSmrg 237f2e35a3aSmrg &query_tcap( "kF", "kind" ); 238f2e35a3aSmrg &query_tcap( "kR", "kri" ); 239f2e35a3aSmrg &query_tcap( "%i", "kRIT" ); 240f2e35a3aSmrg &query_tcap( "#4", "kLFT" ); 241d522f475Smrg} 242d522f475Smrg 243d522f475Smrgif ( defined($opt_a) || defined($opt_e) ) { 244f2e35a3aSmrg &query_tcap( "kD", "kdch1" ); 245f2e35a3aSmrg &query_tcap( "kI", "kich1" ); 246d522f475Smrg 247f2e35a3aSmrg &query_tcap( "kh", "khome" ); 248f2e35a3aSmrg &query_tcap( "\@7", "kend" ); 249f2e35a3aSmrg &query_tcap( "#2", "kHOM" ); 250f2e35a3aSmrg &query_tcap( "*7", "kEND" ); 251d522f475Smrg 252f2e35a3aSmrg &query_tcap( "*6", "kslt" ); 253f2e35a3aSmrg &query_tcap( "#6", "kSLT" ); 254f2e35a3aSmrg &query_tcap( "\@0", "kfnd" ); 255f2e35a3aSmrg &query_tcap( "*0", "kFND" ); 256d522f475Smrg 257f2e35a3aSmrg &query_tcap( "kN", "knp" ); 258f2e35a3aSmrg &query_tcap( "kP", "kpp" ); 25920d2c4d2Smrg 260f2e35a3aSmrg &query_tcap( "%c", "kNXT" ); 261f2e35a3aSmrg &query_tcap( "%e", "kPRV" ); 262d522f475Smrg} 263d522f475Smrg 264d522f475Smrgif ( defined($opt_a) || defined($opt_f) ) { 265f2e35a3aSmrg &query_tcap( "k1", "kf1" ); 266f2e35a3aSmrg &query_tcap( "k2", "kf2" ); 267f2e35a3aSmrg &query_tcap( "k3", "kf3" ); 268f2e35a3aSmrg &query_tcap( "k4", "kf4" ); 269f2e35a3aSmrg &query_tcap( "k5", "kf5" ); 270f2e35a3aSmrg &query_tcap( "k6", "kf6" ); 271f2e35a3aSmrg &query_tcap( "k7", "kf7" ); 272f2e35a3aSmrg &query_tcap( "k8", "kf8" ); 273f2e35a3aSmrg &query_tcap( "k9", "kf9" ); 274f2e35a3aSmrg &query_tcap( "k;", "kf10" ); 275f2e35a3aSmrg &query_tcap( "F1", "kf11" ); 276f2e35a3aSmrg &query_tcap( "F2", "kf12" ); 277f2e35a3aSmrg &query_tcap( "F3", "kf13" ); 278f2e35a3aSmrg &query_tcap( "F4", "kf14" ); 279f2e35a3aSmrg &query_tcap( "F5", "kf15" ); 280f2e35a3aSmrg &query_tcap( "F6", "kf16" ); 281f2e35a3aSmrg &query_tcap( "F7", "kf17" ); 282f2e35a3aSmrg &query_tcap( "F8", "kf18" ); 283f2e35a3aSmrg &query_tcap( "F9", "kf19" ); 284f2e35a3aSmrg &query_tcap( "FA", "kf20" ); 285f2e35a3aSmrg &query_tcap( "FB", "kf21" ); 286f2e35a3aSmrg &query_tcap( "FC", "kf22" ); 287f2e35a3aSmrg &query_tcap( "FD", "kf23" ); 288f2e35a3aSmrg &query_tcap( "FE", "kf24" ); 289f2e35a3aSmrg &query_tcap( "FF", "kf25" ); 290f2e35a3aSmrg &query_tcap( "FG", "kf26" ); 291f2e35a3aSmrg &query_tcap( "FH", "kf27" ); 292f2e35a3aSmrg &query_tcap( "FI", "kf28" ); 293f2e35a3aSmrg &query_tcap( "FJ", "kf29" ); 294f2e35a3aSmrg &query_tcap( "FK", "kf30" ); 295f2e35a3aSmrg &query_tcap( "FL", "kf31" ); 296f2e35a3aSmrg &query_tcap( "FM", "kf32" ); 297f2e35a3aSmrg &query_tcap( "FN", "kf33" ); 298f2e35a3aSmrg &query_tcap( "FO", "kf34" ); 299f2e35a3aSmrg &query_tcap( "FP", "kf35" ); 300f2e35a3aSmrg &query_tcap( "FQ", "kf36" ); 301f2e35a3aSmrg &query_tcap( "FR", "kf37" ); 302f2e35a3aSmrg &query_tcap( "FS", "kf38" ); 303f2e35a3aSmrg &query_tcap( "FT", "kf39" ); 304f2e35a3aSmrg &query_tcap( "FU", "kf40" ); 305f2e35a3aSmrg &query_tcap( "FV", "kf41" ); 306f2e35a3aSmrg &query_tcap( "FW", "kf42" ); 307f2e35a3aSmrg &query_tcap( "FX", "kf43" ); 308f2e35a3aSmrg &query_tcap( "FY", "kf44" ); 309f2e35a3aSmrg &query_tcap( "FZ", "kf45" ); 310f2e35a3aSmrg &query_tcap( "Fa", "kf46" ); 311f2e35a3aSmrg &query_tcap( "Fb", "kf47" ); 312f2e35a3aSmrg &query_tcap( "Fc", "kf48" ); 313f2e35a3aSmrg &query_tcap( "Fd", "kf49" ); 314f2e35a3aSmrg &query_tcap( "Fe", "kf50" ); 315f2e35a3aSmrg &query_tcap( "Ff", "kf51" ); 316f2e35a3aSmrg &query_tcap( "Fg", "kf52" ); 317f2e35a3aSmrg &query_tcap( "Fh", "kf53" ); 318f2e35a3aSmrg &query_tcap( "Fi", "kf54" ); 319f2e35a3aSmrg &query_tcap( "Fj", "kf55" ); 320f2e35a3aSmrg &query_tcap( "Fk", "kf56" ); 321f2e35a3aSmrg &query_tcap( "Fl", "kf57" ); 322f2e35a3aSmrg &query_tcap( "Fm", "kf58" ); 323f2e35a3aSmrg &query_tcap( "Fn", "kf59" ); 324f2e35a3aSmrg &query_tcap( "Fo", "kf60" ); 325f2e35a3aSmrg &query_tcap( "Fp", "kf61" ); 326f2e35a3aSmrg &query_tcap( "Fq", "kf62" ); 327f2e35a3aSmrg &query_tcap( "Fr", "kf63" ); 328d522f475Smrg} 329d522f475Smrg 330d522f475Smrgif ( defined($opt_a) || defined($opt_k) ) { 331f2e35a3aSmrg &query_tcap( "K1", "ka1" ); 332f2e35a3aSmrg &query_tcap( "K3", "ka3" ); 333f2e35a3aSmrg &query_tcap( "K4", "kc1" ); 334f2e35a3aSmrg &query_tcap( "K5", "kc3" ); 335d522f475Smrg} 336d522f475Smrg 337d522f475Smrgif ( defined($opt_a) || defined($opt_m) ) { 338f2e35a3aSmrg &query_tcap( "kB", "kcbt" ); 339f2e35a3aSmrg &query_tcap( "kC", "kclr" ); 340f2e35a3aSmrg &query_tcap( "&8", "kund" ); 341d522f475Smrg 342f2e35a3aSmrg &query_tcap( "kb", "kbs" ); 343d522f475Smrg 344f2e35a3aSmrg &query_tcap( "%1", "khlp" ); 345f2e35a3aSmrg &query_tcap( "#1", "kHLP" ); 346d522f475Smrg 347f2e35a3aSmrg &query_tcap( "Co", "colors" ); 348f2e35a3aSmrg &query_tcap( "Co", "RGB" ) if ($opt_i); 349d522f475Smrg} 350d522f475Smrg 351913cc679Smrgif ( defined($opt_x) ) { 352f2e35a3aSmrg &query_extended($opt_x); 353d522f475Smrg} 35420d2c4d2Smrg 355913cc679Smrgif ( defined($opt_X) ) { 356913cc679Smrg if ( defined($opt_c) ) { 357f2e35a3aSmrg &query_extended("DN"); 358f2e35a3aSmrg &query_extended("UP"); 359f2e35a3aSmrg &query_extended("LFT"); 360f2e35a3aSmrg &query_extended("RIT"); 361913cc679Smrg } 362913cc679Smrg if ( defined($opt_e) ) { 363f2e35a3aSmrg &query_extended("DC"); 364f2e35a3aSmrg &query_extended("END"); 365f2e35a3aSmrg &query_extended("HOM"); 366f2e35a3aSmrg &query_extended("IC"); 367f2e35a3aSmrg &query_extended("NXT"); 368f2e35a3aSmrg &query_extended("PRV"); 369913cc679Smrg } 37020d2c4d2Smrg} 371f2e35a3aSmrg 372f2e35a3aSmrg&finish_query if ($opt_q); 373f2e35a3aSmrg 374f2e35a3aSmrg1; 375