#!/usr/bin/env perl # $XTermId: sgrPushPop2.pl,v 1.4 2020/12/13 15:05:06 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2019,2020 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- use strict; use warnings; use Getopt::Std; $| = 1; our ( $opt_b, $opt_n, $opt_r ); $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('bn:r:') || die( "Usage: $0 [options]\n Options:\n -b color backgrounds instead of foregrounds -n NUM limit test to NUM rows (default: 9) -r NUM rotate example-columns (e.g, -r1 puts direct-color in middle) " ); $opt_n = 9 unless ( defined $opt_n ); $opt_r = 0 unless ( defined $opt_r ); our @xterm_ansi = ( 0x000000, #black 0xcd0000, #red3 0x00cd00, #green3 0xcdcd00, #yellow3 0x0000ee, #blue2 0xcd00cd, #magenta3 0x00cdcd, #cyan3 0xe5e5e5 #gray90 ); # The lengths in @example_title differ to ensure that the trailing "END!" # should be the same color as the middle column, regardless of "-r" rotation. our $example_title = "COLOR-"; our @example_title = ( "Indexed", "ANSI8", "Direct" ); # demonstrate selective SGR pop by a two-level test where the top-level has # ANSI colors, while the lower-level iterates over a color test-pattern, # alternating between direct-color and indexed-colors. sub choose_fgbg($$) { my $fg = shift; my $bg = shift; my $result = $opt_b ? $bg : $fg; return $result; } sub choose_column($) { my $code = shift; return ( $code + $opt_r ) % 3; } sub pushSGR($) { my $params = shift; printf "\x1b[%s#{", $params; } sub popSGR() { printf "\x1b[#}"; } sub mark_l() { printf " {"; } sub mark_r() { printf "} "; } sub standard_example() { &mark_l; my $text = $example_title . $example_title[1]; for my $n ( 0 .. length($text) - 1 ) { printf "\x1b[%dm", ( $n % 7 ) + 1 + &choose_fgbg( 30, 40 ); printf "%s", substr( $text, $n, 1 ); } &mark_r; } # The first 16 colors of xterm-256's palette match the ANSI+aixterm range. # Do not imitate the bold-colors. sub indexed_example() { &mark_l; my $text = $example_title . $example_title[0]; for my $n ( 0 .. length($text) - 1 ) { my $c = ( $n % 7 ) + 1; printf "\x1b[%d;5:%dm", &choose_fgbg( 38, 48 ), $c; printf "%s", substr( $text, $n, 1 ); } &mark_r; } # Imitate the "ANSI" colors from xterm's palette. # (Again bold colors are not imitated here). sub direct_example() { &mark_l; my $text = $example_title . $example_title[2]; for my $n ( 0 .. length($text) - 1 ) { my $c = ( $n % 7 ) + 1; my $r = ( $xterm_ansi[$c] / ( 256 * 256 ) ) % 256; my $g = ( $xterm_ansi[$c] / (256) ) % 256; my $b = ( $xterm_ansi[$c] ) % 256; printf "\x1b[%d;2:1:%d:%d:%dm", &choose_fgbg( 38, 48 ), $r, $g, $b; printf "%s", substr( $text, $n, 1 ); } &mark_r; } sub run_example($) { my $column = shift; &indexed_example if ( &choose_column($column) == 0 ); &standard_example if ( &choose_column($column) == 1 ); &direct_example if ( &choose_column($column) == 2 ); } sub video_name($) { my $code = shift; my $result = "?"; $result = "normal" if ( $code == 0 ); $result = "bold" if ( $code == 1 ); $result = "faint" if ( $code == 2 ); $result = "italicized" if ( $code == 3 ); $result = "underlined" if ( $code == 4 ); $result = "blink" if ( $code == 5 ); $result = "inverse" if ( $code == 7 ); $result = "crossed-out" if ( $code == 9 ); $result = "double-underlined" if ( $code == 21 ); return $result; } sub reset_video() { printf "\x1b[m"; } sub set_video($) { my $row = shift; my $param = ""; my $cycle = 9; $param = 0 if ( ( $row % $cycle ) == 0 ); $param = 1 if ( ( $row % $cycle ) == 1 ); $param = 2 if ( ( $row % $cycle ) == 2 ); $param = 3 if ( ( $row % $cycle ) == 3 ); $param = 4 if ( ( $row % $cycle ) == 4 ); $param = 5 if ( ( $row % $cycle ) == 5 ); $param = 7 if ( ( $row % $cycle ) == 6 ); $param = 9 if ( ( $row % $cycle ) == 7 ); $param = 21 if ( ( $row % $cycle ) == 8 ); printf "%-20s", &video_name($param); printf "\x1b[%dm", $param; } printf "\x1b[H\x1b[J"; &pushSGR(""); printf "\x1b[40;37mSetting ambient colors to white-on-black\n"; # The three columns (indexed, ANSI, direct) will look similar. &pushSGR(""); printf "Testing white-on-black with columns %s,%s,%s\n", $example_title[ &choose_column(0) ], $example_title[ &choose_column(1) ], $example_title[ &choose_column(2) ]; for my $row ( 0 .. $opt_n ) { &pushSGR("30;31"); # save/restore only foreground/background color &set_video($row); # this attribute is set for the whole row &run_example(0); &popSGR; &run_example(1); &pushSGR("30;31"); # save/restore only foreground/background color &run_example(2); &popSGR; printf "END!"; # this is in the last color used in the middle column &reset_video(); printf "\n"; } &popSGR; printf "The ambient colors should still be white-on-black.\n"; &popSGR; printf "Now we should be back to whatever it was before we got here.\n"; 1;