query-status.pl revision f2e35a3a
1913cc679Smrg#!/usr/bin/env perl
2f2e35a3aSmrg# $XTermId: query-status.pl,v 1.7 2019/05/19 08:57:41 tom Exp $
3913cc679Smrg# -----------------------------------------------------------------------------
4913cc679Smrg# this file is part of xterm
5913cc679Smrg#
6f2e35a3aSmrg# Copyright 2017-2018,2019 by Thomas E. Dickey
7913cc679Smrg#
8913cc679Smrg#                         All Rights Reserved
9913cc679Smrg#
10913cc679Smrg# Permission is hereby granted, free of charge, to any person obtaining a
11913cc679Smrg# copy of this software and associated documentation files (the
12913cc679Smrg# "Software"), to deal in the Software without restriction, including
13913cc679Smrg# without limitation the rights to use, copy, modify, merge, publish,
14913cc679Smrg# distribute, sublicense, and/or sell copies of the Software, and to
15913cc679Smrg# permit persons to whom the Software is furnished to do so, subject to
16913cc679Smrg# the following conditions:
17913cc679Smrg#
18913cc679Smrg# The above copyright notice and this permission notice shall be included
19913cc679Smrg# in all copies or substantial portions of the Software.
20913cc679Smrg#
21913cc679Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22913cc679Smrg# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23913cc679Smrg# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24913cc679Smrg# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
25913cc679Smrg# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26913cc679Smrg# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27913cc679Smrg# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28913cc679Smrg#
29913cc679Smrg# Except as contained in this notice, the name(s) of the above copyright
30913cc679Smrg# holders shall not be used in advertising or otherwise to promote the
31913cc679Smrg# sale, use or other dealings in this Software without prior written
32913cc679Smrg# authorization.
33913cc679Smrg# -----------------------------------------------------------------------------
34913cc679Smrg# Test the status features of xterm using DECRQSS.
35913cc679Smrg#
36913cc679Smrg# TODO: use Term::ReadKey rather than system/stty
37913cc679Smrg
38913cc679Smrguse strict;
39913cc679Smrguse warnings;
40913cc679Smrg
41913cc679Smrguse Getopt::Std;
42913cc679Smrguse IO::Handle;
43913cc679Smrg
44f2e35a3aSmrgour ($opt_8);
45f2e35a3aSmrg
46f2e35a3aSmrg$Getopt::Std::STANDARD_HELP_VERSION = 1;
47f2e35a3aSmrg&getopts('8') || die(
48913cc679Smrg    "Usage: $0 [options]\n
49913cc679SmrgOptions:\n
50913cc679Smrg  -8      use 8-bit controls
51f2e35a3aSmrg
52f2e35a3aSmrgOptions which use C1 controls may not work with UTF-8.
53913cc679Smrg"
54913cc679Smrg);
55913cc679Smrg
56f2e35a3aSmrgour $ST = $opt_8 ? "\x9c" : "\x1b\\";
57913cc679Smrg
58913cc679Smrgour %suffixes;
59913cc679Smrg$suffixes{DECSCA}   = '"q';
60913cc679Smrg$suffixes{DECSCL}   = '"p';
61913cc679Smrg$suffixes{DECSTBM}  = 'r';
62913cc679Smrg$suffixes{DECSLRM}  = 's';
63913cc679Smrg$suffixes{SGR}      = 'm';
64913cc679Smrg$suffixes{DECSCUSR} = ' q';
65913cc679Smrg
66913cc679Smrgsub get_reply($) {
67913cc679Smrg    open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n");
68913cc679Smrg    autoflush TTY 1;
69913cc679Smrg    my $old = `stty -g`;
70913cc679Smrg    system "stty raw -echo min 0 time 5";
71913cc679Smrg
72913cc679Smrg    print TTY @_;
73913cc679Smrg    my $reply = <TTY>;
74913cc679Smrg    close TTY;
75913cc679Smrg    system "stty $old";
76913cc679Smrg    if ( defined $reply ) {
77913cc679Smrg        die("^C received\n") if ( "$reply" eq "\003" );
78913cc679Smrg    }
79913cc679Smrg    return $reply;
80913cc679Smrg}
81913cc679Smrg
82913cc679Smrgsub visible($) {
83913cc679Smrg    my $reply = $_[0];
84913cc679Smrg    my $n;
85913cc679Smrg    my $result = "";
86913cc679Smrg    for ( $n = 0 ; $n < length($reply) ; ) {
87913cc679Smrg        my $c = substr( $reply, $n, 1 );
88913cc679Smrg        if ( $c =~ /[[:print:]]/ ) {
89913cc679Smrg            $result .= $c;
90913cc679Smrg        }
91913cc679Smrg        else {
92913cc679Smrg            my $k = ord substr( $reply, $n, 1 );
93913cc679Smrg            if ( ord $k == 0x1b ) {
94913cc679Smrg                $result .= "\\E";
95913cc679Smrg            }
96913cc679Smrg            elsif ( $k == 0x7f ) {
97913cc679Smrg                $result .= "^?";
98913cc679Smrg            }
99913cc679Smrg            elsif ( $k == 32 ) {
100913cc679Smrg                $result .= "\\s";
101913cc679Smrg            }
102913cc679Smrg            elsif ( $k < 32 ) {
103913cc679Smrg                $result .= sprintf( "^%c", $k + 64 );
104913cc679Smrg            }
105913cc679Smrg            elsif ( $k > 128 ) {
106913cc679Smrg                $result .= sprintf( "\\%03o", $k );
107913cc679Smrg            }
108913cc679Smrg            else {
109913cc679Smrg                $result .= chr($k);
110913cc679Smrg            }
111913cc679Smrg        }
112913cc679Smrg        $n += 1;
113913cc679Smrg    }
114913cc679Smrg
115913cc679Smrg    return $result;
116913cc679Smrg}
117913cc679Smrg
118913cc679Smrgsub query_one($) {
119913cc679Smrg    my $name   = shift;
120913cc679Smrg    my $suffix = $suffixes{$name};
121913cc679Smrg    my $prefix = $opt_8 ? "\x90" : "\x1bP";
122913cc679Smrg    my $reply;
123913cc679Smrg    my $n;
124f2e35a3aSmrg    my $st    = $opt_8 ? "\x9c" : qr/\x1b\\/;
125913cc679Smrg    my $DCS   = qr/${prefix}/;
126913cc679Smrg    my $match = qr/${DCS}.*${st}/;
127913cc679Smrg
128913cc679Smrg    $reply = get_reply( $prefix . '$q' . $suffix . $ST );
129913cc679Smrg
130913cc679Smrg    printf "%-10s query{%s}%*s", $name,    #
131913cc679Smrg      &visible($suffix),                   #
132913cc679Smrg      4 - length($suffix), " ";
133913cc679Smrg
134913cc679Smrg    if ( defined $reply ) {
135913cc679Smrg        printf "%2d ", length($reply);
136913cc679Smrg        if ( $reply =~ /${match}/ ) {
137913cc679Smrg
138913cc679Smrg            $reply =~ s/^${DCS}//;
139913cc679Smrg            $reply =~ s/^;//;
140913cc679Smrg            $reply =~ s/${st}$//;
141913cc679Smrg        }
142913cc679Smrg        else {
143913cc679Smrg            printf "? ";
144913cc679Smrg        }
145913cc679Smrg
146913cc679Smrg        printf "{%s}", visible($reply);
147913cc679Smrg    }
148913cc679Smrg    printf "\n";
149913cc679Smrg}
150913cc679Smrg
151f2e35a3aSmrgprintf "\x1b G" if ($opt_8);
152f2e35a3aSmrg
153913cc679Smrgif ( $#ARGV >= 0 ) {
154913cc679Smrg    while ( $#ARGV >= 0 ) {
155913cc679Smrg        &query_one( shift @ARGV );
156913cc679Smrg    }
157913cc679Smrg}
158913cc679Smrgelse {
159913cc679Smrg    for my $key ( sort keys %suffixes ) {
160913cc679Smrg        &query_one($key);
161913cc679Smrg    }
162913cc679Smrg}
163f2e35a3aSmrg
164f2e35a3aSmrgprintf "\x1b F" if ($opt_8);
165