@ -1140,7 +1140,12 @@ namespace eval punk::console {
return
return
}
}
#tailcall punk::ansi::a {*}$args
#tailcall punk::ansi::a {*}$args
::punk::ansi::a {*}$args
variable is_vt52
if {$is_vt52} {
return
} else {
::punk::ansi::a {*}$args
}
}
}
lappend PUNKARGS_aliases {::punk::console::code_a? ::punk::ansi::a?}
lappend PUNKARGS_aliases {::punk::console::code_a? ::punk::ansi::a?}
proc code_a? {args} {
proc code_a? {args} {
@ -1537,11 +1542,11 @@ namespace eval punk::console {
set cell_size ""
set cell_size ""
set cell_size_fallback 10x20
set cell_size_fallback 10x20
#todo - change -inoutchannels to -terminalobject with prebuilt default
#todo - change -console to -terminalobject with prebuilt default
punk::args::define {
punk::args::define {
@id -id ::punk::console::cell_size
@id -id ::punk::console::cell_size
-inoutchannels -default {stdin stdout} -type list
-console -default {stdin stdout} -type list
@values -min 0 -max 1
@values -min 0 -max 1
newsize -default "" -help\
newsize -default "" -help\
"character cell pixel dimensions WxH
"character cell pixel dimensions WxH
@ -1549,7 +1554,7 @@ namespace eval punk::console {
}
}
proc cell_size {args} {
proc cell_size {args} {
set argd [punk::args::parse $args -cache 1 withid ::punk::console::cell_size]
set argd [punk::args::parse $args -cache 1 withid ::punk::console::cell_size]
set inoutchannels [dict get $argd opts -inoutchannels ]
set terminal [dict get $argd opts -console ]
set newsize [dict get $argd values newsize]
set newsize [dict get $argd values newsize]
variable cell_size
variable cell_size
@ -1557,7 +1562,7 @@ namespace eval punk::console {
#query existing setting
#query existing setting
if {$cell_size eq ""} {
if {$cell_size eq ""} {
#not set - try to query terminal's overall dimensions
#not set - try to query terminal's overall dimensions
set pixeldict [punk::console::get_xterm_pixels $inoutch anne ls ]
set pixeldict [punk::console::get_xterm_pixels $term inal]
lassign $pixeldict _w sw _h sh
lassign $pixeldict _w sw _h sh
if {[string is integer -strict $sw] && [string is integer -strict $sh]} {
if {[string is integer -strict $sw] && [string is integer -strict $sh]} {
lassign [punk::console::get_size] _cols columns _rows rows
lassign [punk::console::get_size] _cols columns _rows rows
@ -1651,8 +1656,8 @@ namespace eval punk::console {
set func_con "punk::ansi::cursor_on"
set func_con "punk::ansi::cursor_on"
} else {
} else {
set movefunc "punk::ansi::vt52move"
set movefunc "punk::ansi::vt52move"
set func_coff "punk::ansi::cursor_off_vt52 "
set func_coff "punk::ansi::vt52 cursor_off"
set func_con "punk::ansi::cursor_on_vt52 "
set func_con "punk::ansi::vt52 cursor_on"
}
}
if {[catch {
if {[catch {
#some terminals (conemu on windows) scroll the viewport when we make a big move down like this - a move to 1 1 immediately after cursor_save doesn't seem to fix that.
#some terminals (conemu on windows) scroll the viewport when we make a big move down like this - a move to 1 1 immediately after cursor_save doesn't seem to fix that.
@ -1763,10 +1768,16 @@ namespace eval punk::console {
4 - mode is permanently unset
4 - mode is permanently unset
The response is automatically retrieved from the terminal
The response is automatically retrieved from the terminal
and so should not be displayed unless there is such a
and so should not be displayed unless there is such a
significant delay that the request times out.
significant delay that the request times out.
The value of <s> is returned by the dec_get_mode function.
The value of <s> is returned by the dec_get_mode function.
The delay in retrieving a terminal response can range from
a few ms to 10s of ms depending on the terminal or other
runtime conditions.
In some cases it may be beneficial to call dec_has_mode first,
(which is cached) to reduce the number of queries to the terminal.
}
}
@opts
@opts
-console -type list -minsize 2 -default {stdin stdout}
-console -type list -minsize 2 -default {stdin stdout}
@ -1910,10 +1921,24 @@ namespace eval punk::console {
the sequence:
the sequence:
ESC [ ? <n> $ p
ESC [ ? <n> $ p
Where <n> is an integer identifier.
Where <n> is an integer identifier.
Will return zero if the mode is unsupported, 1|2|3|4 if supported.
The result is cached.
Cached values of 1 or 2 may not represent current state.
${$B}dec_get_mode${$N} or ${$B}dec_has_mode -refresh${$N} should be
used if up-to-date current state of a supported mode is required.
}
}
@opts
@opts
-console -type list -minsize 2 -default {stdin stdout}
-console -type list -minsize 2 -default {stdin stdout}
-refresh -type none
-refresh -type none -help\
"Force a re-test of the mode."
-return -type string -choices {dict result} -default result -choicelabels {
dict\
"Return a dict with keys source and result
source indicates whether the result came
from query or cache."
}
@values -min 1 -max 1
@values -min 1 -max 1
mode -type {int|string} -help\
mode -type {int|string} -help\
"integer for DEC mode, or name as in the dict:
"integer for DEC mode, or name as in the dict:
@ -1925,11 +1950,8 @@ namespace eval punk::console {
lassign [dict values $argd] leaders opts values received
lassign [dict values $argd] leaders opts values received
set console [dict get $opts -console]
set console [dict get $opts -console]
set num_or_name [dict get $values mode]
set num_or_name [dict get $values mode]
if {[dict exists $received -refresh]} {
set do_refresh [dict exists $received -refresh]
set do_refresh 1
set return [dict get $opts -return]
} else {
set do_refresh 0
}
if {[string is integer -strict $num_or_name]} {
if {[string is integer -strict $num_or_name]} {
set m $num_or_name
set m $num_or_name
@ -1952,10 +1974,23 @@ namespace eval punk::console {
set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[\?%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload
set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[\?%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload
set request "\x1b\[?$m\$p"
set request "\x1b\[?$m\$p"
set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex]
set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex]
set has_mode [expr {$payload != 0}]
#set has_mode [expr {$payload != 0}]
dict set dec_has_mode_cache $console $m $has_mode
#we can use the payload result as the response as non-zero responses evaluate to true
set has_mode $payload
if {$has_mode ne ""} {
dict set dec_has_mode_cache $console $m $has_mode
set source "query"
} else {
#don't cache an empty/failed response - review
set has_mode 0
set source "failedquery"
}
} else {
} else {
set has_mode [dict get $dec_has_mode_cache $console $m]
set has_mode [dict get $dec_has_mode_cache $console $m]
set source "cache"
}
if {$return eq "dict"} {
return [dict create result $has_mode source $source]
}
}
return $has_mode
return $has_mode
}
}
@ -1971,64 +2006,148 @@ namespace eval punk::console {
-console -type list -minsize 2 -default {stdin stdout}
-console -type list -minsize 2 -default {stdin stdout}
-test -type none -help\
-test -type none -help\
"Test current value/support for each mode"
"Test current value/support for each mode"
@values -min 0 -max 0
-supported -type none -help\
"Limit results to supported DEC modes"
@values -min 0 -max -1
match -type indexset|string -multiple 1 -optional 1 -help\
"Match code or name"
}]
}]
proc dec_modes {args} {
proc dec_modes {args} {
set argd [punk::args::parse $args withid ::punk::console::dec_modes]
set argd [punk::args::parse $args withid ::punk::console::dec_modes]
lassign [dict values $argd] leaders opts values received
lassign [dict values $argd] leaders opts values received
set terminal [dict get $opts -console]
set terminal [dict get $opts -console]
if {[dict exists $received -test]} {
set do_test [dict exists $received -test]
set do_test 1
set only_supported [dict exists $received -supported]
if {[dict exists $values match]} {
set matches [dict get $values match]
} else {
} else {
set do_test 0
set matches {}
}
}
upvar ::punk::ansi::decmode_data decmode_data
upvar ::punk::ansi::decmode_data decmode_data
upvar ::punk::ansi::decmode_names decmode_names
set t [textblock::class::table new "Dec Modes"]
set t [textblock::class::table new "Dec Modes"]
$t configure -show_header 1 -show_hseps 1
$t configure -show_header 1 -show_hseps 1
$t add_column -headers Code
$t add_column -headers Code
$t add_column -headers Names
$t add_column -headers Names
$t add_column -headers Origin
$t add_column -headers Origin
$t add_column -headers Description
$t add_column -headers Description
$t add_column -headers set-state
$t add_column -headers reset-state
if {$do_test} {
if {$do_test} {
$t add_column -headers Status
$t add_column -headers Status
}
}
dict for {code items} $decmode_data {
set names [dict keys $decmode_names]
if {[llength $matches] == 0} {
#show all entries
set codes [dict keys $decmode_data]
} else {
set codes [list]
foreach m $matches {
if {[punk::lib::is_indexset $m]} {
set defaultmax 10000 ;#some codes are very high e.g foot IME 737769 - but we don't want to default test/scan for hours
#todo set max to actual largest value from indexset
lappend codes {*}[punk::lib::indexset_resolve -base 1 $defaultmax $m]
} else {
foreach nm $names {
if {[string match -nocase $m $nm]} {
set code [dict get $decmode_names $nm]
#only suppress dupes if sequential (display loop will still show multiple entries for the code if it has multiple origin entries)
if {[lindex $codes end] ne $code} {
lappend codes [dict get $decmode_names $nm]
}
}
}
}
}
}
#dict for {code items} $decmode_data {}
foreach code $codes {
if {[dict exists $decmode_data $code]} {
set items [dict get $decmode_data $code]
} else {
set items [list [dict create origin ? description "" names "" set-state "" reset-state ""]]
}
set colour ""
set colour ""
set set_state_colour ""
set reset_state_colour ""
set RST ""
set RST ""
if {$do_test} {
if {$do_test} {
set testresult [dec_get_mode $code]
#dec_has_mode can be cached - in which case only 0|3|4 can be relied upon without re-querying
set hasmode_dict [dec_has_mode -console $terminal -return dict $code]
switch -- [dict get $hasmode_dict result] {
0 {
if {$only_supported} {
continue
}
if {[dict get $hasmode_dict source] eq "failedquery"} {
set testresult "no response"
} else {
set testresult 0
}
}
1 - 2 {
if {[dict get $hasmode_dict source] eq "cache"} {
#a terminal query is required
set testresult [dec_get_mode -console $terminal $code]
} else {
set testresult [dict get $hasmode_dict result]
if {![string is integer -strict $testresult]} {
set testresult "No response"
}
}
}
default {
#3|4 - permanently enabled or permanently disabled
set testresult [dict get $hasmode_dict result]
}
}
switch -- $testresult {
switch -- $testresult {
0 {
0 {
set colour [punk::ansi::a+ red bold]
set colour [punk::ansi::a+ red bold]
}
}
1 {
1 {
set colour [punk::ansi::a+ green]
set colour [punk::ansi::a+ green]
set set_state_colour $colour
}
}
2 {
2 {
set colour [punk::ansi::a+ yellow bold]
set colour [punk::ansi::a+ yellow bold]
set reset_state_colour $colour
}
}
3 {
3 {
set colour [punk::ansi::a+ green]
set colour [punk::ansi::a+ green]
set set_state_colour $colour
}
}
4 {
4 {
set colour [punk::ansi::a+ yellow bold]
set colour [punk::ansi::a+ yellow bold]
set reset_state_colour $colour
}
}
default {
default {
#unexpected
#failedquery
set colour [punk::ansi::a+ red bold]
}
}
}
}
if {$colour ne ""} {
if {$colour ne ""} {
set RST "\x1b\[m"
set RST "\x1b\[m"
}
}
set testdisplay $colour$testresult$RST
set testdisplay $colour$testresult$RST
} else {
if {$only_supported} {
#dec_has_mode still queries terminal - but is cached if a response was received
if {[dec_has_mode -console $terminal $code] == 0} {
continue
}
}
}
}
foreach itm $items {
foreach itm $items {
set code $colour$code$RST
set code $colour$code$RST
set names $colour[dict get $itm names]$RST
set names $colour[dict get $itm names]$RST
set origin [dict get $itm origin]
set origin [dict get $itm origin]
set desc [dict get $itm description]
set desc [dict get $itm description]
set row [list $code [join $names \n] $origin $desc]
set set_state $set_state_colour[dict get $itm set-state]$RST
set reset_state $reset_state_colour[dict get $itm reset-state]$RST
set row [list $code [join $names \n] $origin $desc $set_state $reset_state]
if {$do_test} {
if {$do_test} {
lappend row $testdisplay
lappend row $testdisplay
}
}
@ -2059,6 +2178,12 @@ namespace eval punk::console {
#-console -type list -typesynopsis {{${$I}inputchan${$NI} ${$I}outputchan${$NI}}} -minsize 2 -default {stdin stdout}
#-console -type list -typesynopsis {{${$I}inputchan${$NI} ${$I}outputchan${$NI}}} -minsize 2 -default {stdin stdout}
-console -type list -minsize 2 -default {stdin stdout}
-console -type list -minsize 2 -default {stdin stdout}
-refresh -type none
-refresh -type none
-return -type string -choices {dict result} -default result -choicelabels {
dict\
"Return a dict with keys source and result
source indicates whether the result came
from query or cache."
}
@values -min 1 -max 1
@values -min 1 -max 1
mode -type {int|string} -help\
mode -type {int|string} -help\
"integer for ANSI mode, or name as in the dict:
"integer for ANSI mode, or name as in the dict:
@ -2070,11 +2195,8 @@ namespace eval punk::console {
lassign [dict values $argd] leaders opts values received
lassign [dict values $argd] leaders opts values received
set console [dict get $opts -console]
set console [dict get $opts -console]
set num_or_name [dict get $values mode]
set num_or_name [dict get $values mode]
if {[dict exists $received -refresh]} {
set return [dict get $opts -return]
set do_refresh 1
set do_refresh [dict exists $received -refresh]
} else {
set do_refresh 0
}
if {[string is integer -strict $num_or_name]} {
if {[string is integer -strict $num_or_name]} {
set m $num_or_name
set m $num_or_name
@ -2097,10 +2219,22 @@ namespace eval punk::console {
set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload
set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload
set request "\x1b\[$m\$p"
set request "\x1b\[$m\$p"
set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex]
set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex]
set has_mode [expr {$payload != 0}]
#set has_mode [expr {$payload != 0}]
dict set ansi_has_mode_cache $console $m $has_mode
set has_mode $payload
if {$has_mode ne ""} {
dict set ansi_has_mode_cache $console $m $has_mode
set source "query"
} else {
#don't cache an empty/failed response - review
set has_mode 0
set source "failedquery"
}
} else {
} else {
set has_mode [dict get $ansi_has_mode_cache $console $m]
set has_mode [dict get $ansi_has_mode_cache $console $m]
set source "cache"
}
if {$return eq "dict"} {
return [dict create result $has_mode source $source]
}
}
return $has_mode
return $has_mode
}
}
@ -2272,23 +2406,23 @@ namespace eval punk::console {
-console -type list -minsize 2 -default {stdin stdout}
-console -type list -minsize 2 -default {stdin stdout}
-test -type none -help\
-test -type none -help\
"Test current value/support for each mode"
"Test current value/support for each mode"
-supported -type none -help\
"Limit results to supported ANSI modes"
@values -min 0 -max -1
@values -min 0 -max -1
match -type indexset|string -multiple 1 -optional 1
match -type indexset|string -multiple 1 -optional 1 -help\
"Match code or name"
}]
}]
proc ansi_modes {args} {
proc ansi_modes {args} {
set argd [punk::args::parse $args withid ::punk::console::ansi_modes]
set argd [punk::args::parse $args withid ::punk::console::ansi_modes]
lassign [dict values $argd] leaders opts values received
lassign [dict values $argd] leaders opts values received
set terminal [dict get $opts -console]
set terminal [dict get $opts -console]
if {[dict exists $received -test]} {
set do_test [dict exists $received -test]
set do_test 1
} else {
set do_test 0
}
if {[dict exists $values match]} {
if {[dict exists $values match]} {
set matches [dict get $values match]
set matches [dict get $values match]
} else {
} else {
set matches {}
set matches {}
}
}
set only_supported [dict exists $received -supported]
upvar ::punk::ansi::ansimode_data ansimode_data
upvar ::punk::ansi::ansimode_data ansimode_data
upvar ::punk::ansi::ansimode_names ansimode_names
upvar ::punk::ansi::ansimode_names ansimode_names
@ -2312,11 +2446,42 @@ namespace eval punk::console {
set codes [list]
set codes [list]
foreach m $matches {
foreach m $matches {
if {[punk::lib::is_indexset $m]} {
if {[punk::lib::is_indexset $m]} {
lappend codes {*}[punk::lib::indexset_resolve -base 1 [dict size $ansimode_data] $m]
set iparts [split $m ,]
#determine the largest index requested - which may be greater than the defined range if explicitly specified
#(allow scanning for unusual ansi modes above 22 - *some* known to exist - private modes should use DECSET DECRESET instead)
#above 22 values seem to be mainly from SCOANSI and Wyse terminals
set maxint [dict size $ansimode_data]
foreach i $iparts {
if {[string is integer -strict $i]} {
if {$i > $maxint} {
set maxint $i
}
} else {
if {![string match *end* $i]} {
lassign [split [string map [list .. \uFFEF] $i] \uFFEF] a b
if {$a > $b} {
if {$a > $maxint} {
set maxint $a
}
} else {
if {$b > $maxint} {
set maxint $b
}
}
}
}
}
puts "---> maxint: $maxint"
lappend codes {*}[punk::lib::indexset_resolve -base 1 $maxint $m]
} else {
} else {
foreach nm $names {
foreach nm $names {
if {[string match -nocase $m $nm]} {
if {[string match -nocase $m $nm]} {
lappend codes [dict get $ansimode_names $nm]
set code [dict get $ansimode_names $nm]
#only suppress dupes if sequential (display loop will still show multiple entries for the code if it has multiple origin entries)
if {[lindex $codes end] ne $code} {
lappend codes [dict get $ansimode_names $nm]
}
}
}
}
}
}
}
@ -2325,13 +2490,46 @@ namespace eval punk::console {
#dict for {code items} $ansimode_data {}
#dict for {code items} $ansimode_data {}
foreach code $codes {
foreach code $codes {
set items [dict get $ansimode_data $code]
if {[dict exists $ansimode_data $code]} {
set items [dict get $ansimode_data $code]
} else {
set items [list [dict create origin ? description "" names "" set-state "" reset-state ""]]
}
set colour ""
set colour ""
set set_state_colour ""
set set_state_colour ""
set reset_state_colour ""
set reset_state_colour ""
set RST ""
set RST ""
if {$do_test} {
if {$do_test} {
set testresult [ansi_get_mode $code]
set hasmode_dict [ansi_has_mode -console $terminal -return dict $code]
switch -- [dict get $hasmode_dict result] {
0 {
if {$only_supported} {
continue
}
if {[dict get $hasmode_dict source] eq "failedquery"} {
set testresult "no response"
} else {
set testresult 0
}
}
1 - 2 {
if {[dict get $hasmode_dict source] eq "cache"} {
#a terminal query is required
set testresult [ansi_get_mode -console $terminal $code]
} else {
set testresult [dict get $hasmode_dict result]
if {![string is integer -strict $testresult]} {
set testresult "No response"
}
}
}
default {
#3|4 - permanently enabled or permanently disabled
set testresult [dict get $hasmode_dict result]
}
}
#set testresult [ansi_get_mode $code]
switch -- $testresult {
switch -- $testresult {
0 {
0 {
set colour [punk::ansi::a+ red bold]
set colour [punk::ansi::a+ red bold]
@ -2360,6 +2558,13 @@ namespace eval punk::console {
set RST "\x1b\[m"
set RST "\x1b\[m"
}
}
set testdisplay $colour$testresult$RST
set testdisplay $colour$testresult$RST
} else {
if {$only_supported} {
#ansi_has_mode still queries terminal - but is cached if a response was received
if {[ansi_has_mode -console $terminal $code] == 0} {
continue
}
}
}
}
foreach itm $items {
foreach itm $items {
set code $colour$code$RST
set code $colour$code$RST
@ -2381,35 +2586,47 @@ namespace eval punk::console {
return $out
return $out
}
}
#see https://vt100.net/dec/ek-vt520-rm.pdf
set DECRQSS_DATA {
set DECRQSS_DATA {
"Assign Color" DECAC ",|"
"Alternate Text Color" DECATC ",\}"
"CRT Saver Timing" DECCRTST "-q"
"Down Line Load Allocation" DECDLDA ",z"
"Energy Save Timing" DECSEST "-r"
"Select Auto Repeat Rate" DECARR "-p"
"Select Active Status Display" DECSASD "$\}"
"Select Active Status Display" DECSASD "$\}"
"Select Attribute Change Extent" DECSACE "*x"
"Select Attribute Change Extent" DECSACE "*x"
"Set Character Attribute" DECSCA "\"q"
"Set Character Attribute" DECSCA "\"q"
"Set Conformance Level" DECSCL "\"p"
"Select Communication Port" DECSCP "*u "
"Set Columns Per Page" DECSCPP "\$|"
"Set Columns Per Page" DECSCPP "\$|"
"Set Conformance Level" DECSCL "\"p"
"Select Communication Speed" DECSCS "*r"
"Set Cursor Style" DECSCUSR " q"
"Select Disconnect Delay Time" DECSDDT "\$q"
"Select Digital Printed Data Type" DECSDPT "(p"
"Select Flow Control Type" DECSFC "*s"
"Set Key Click Volume" DECSKCV " r"
"Set Lock Key Style" DECSLCK " v"
"Set Left and Right Margins" DECSLRM "s"
"Set Lines Per Page" DECSLPP "t"
"Set Lines Per Page" DECSLPP "t"
"Set Margin Bell Volume" DECSMBV " u"
"Set Number of Lines per Screen" DECSNLS "*|"
"Set Number of Lines per Screen" DECSNLS "*|"
"Set Status Line Type" DECSSDT "$~"
"Session Page Memory Allocation" DECSPMA ",x"
"Set Left and Right Margins" DECSLRM "s"
"Set Port Parameter" DECSPP "\+w"
"Set Top and Bottom Margins" DECSTBM "r"
"Select ProPrinter Character Set" DECSPPCS "*p"
"Set Graphic Rendition" SGR "m"
"Select Set-Up Language" DECSSL "p"
"Select Printer Type" DECSPRTT "\$s"
"Select Printer Type" DECSPRTT "\$s"
"Select Refresh Rate" DECSRFR "\"t"
"Select Refresh Rate" DECSRFR "\"t"
"Select Digital Printed Data Type" DECSDPT "(p"
"Select ProPrinter Character Set" DECSPPCS "*p"
"Select Communication Speed" DECSCS "*r"
"Select Communication Port" DECSCP "*u"
"Set Scroll Speed" DECSSCLS " p"
"Set Scroll Speed" DECSSCLS " p"
"Set Cursor Style" DECSCUSR " q"
"Set Status Line Type" DECSSDT "$~"
"Set Key Click Volume" DECSKCV " r"
"Select Set-Up Language" DECSSL "p"
"Set Warning Bell Volume" DECSWBV " t"
"Set Top and Bottom Margins" DECSTBM "r"
"Set Margin Bell Volume" DECSMBV " u"
"Select Color Lookup Table" DECSTGLT ")\{"
"Set Lock Key Style" DECSLCK " v"
"Select Flow Control Type" DECSFC "*s"
"Select Disconnect Delay Time" DECSDDT "\$q"
"Set Transmit Rate Limit" DECSTRL "u"
"Set Transmit Rate Limit" DECSTRL "u"
"Set Port Parameter" DECSPP "\+w"
"Set Warning Bell Volume" DECSWBV " t"
"Select Zero Symbol" DECSZS ",\{"
"Terminal Mode Emulation" DECTME " ~"
"Set Graphic Rendition" SGR "m"
"invalid" invalid ".."
}
}
set DECRQSS_DICT [dict create]
set DECRQSS_DICT [dict create]
foreach {desc name str} $DECRQSS_DATA {
foreach {desc name str} $DECRQSS_DATA {
@ -2461,12 +2678,12 @@ namespace eval punk::console {
set c1 [string index $payload 0]
set c1 [string index $payload 0]
switch -- $c1 {
switch -- $c1 {
0 {
0 {
error "dec_request_setting - terminal doesn't recognise request '[punk::ansi::ansistring VIEW $request]' as valid "
error "dec_request_setting - terminal doesn't support querying settings for $name '[punk::ansi::ansistring VIEW $request]' "
}
}
1 {}
1 {}
default {
default {
#shouldn't get here
#probable timeout - terminal doesn't recognise/respond
error "dec_request_setting - unrecognised response to request '[punk::ansi::ansistring VIEW $request]'. payload: [punk::ansi::ansistring VIEW $payload]"
error "dec_request_setting - unrecognised or missing response to request '[punk::ansi::ansistring VIEW $request]'. payload: [punk::ansi::ansistring VIEW $payload]"
}
}
}
}
#strip leading 1$r
#strip leading 1$r
@ -2772,7 +2989,12 @@ namespace eval punk::console {
puts -nonewline stdout [punk::ansi::clear_above]
puts -nonewline stdout [punk::ansi::clear_above]
}
}
proc clear_below {} {
proc clear_below {} {
puts -nonewline stdout [punk::ansi::clear_below]
upvar ::punk::console::is_vt52 is_vt52
if {!$is_vt52} {
puts -nonewline stdout [punk::ansi::clear_below]
} else {
puts -nonewline stdout [punk::ansi::vt52clear_below]
}
}
}
proc clear_all {} {
proc clear_all {} {
puts -nonewline stdout [punk::ansi::clear_all]
puts -nonewline stdout [punk::ansi::clear_all]
@ -2785,7 +3007,7 @@ namespace eval punk::console {
if {!$is_vt52} {
if {!$is_vt52} {
puts -nonewline stdout [punk::ansi::cursor_on]
puts -nonewline stdout [punk::ansi::cursor_on]
} else {
} else {
puts -nonewline stdout [punk::ansi::cursor_on_vt52 ]
puts -nonewline stdout [punk::ansi::vt52 cursor_on]
}
}
}
}
proc cursor_off {} {
proc cursor_off {} {
@ -2793,7 +3015,7 @@ namespace eval punk::console {
if {!$is_vt52} {
if {!$is_vt52} {
puts -nonewline stdout [punk::ansi::cursor_off]
puts -nonewline stdout [punk::ansi::cursor_off]
} else {
} else {
puts -nonewline stdout [punk::ansi::cursor_off_vt52 ]
puts -nonewline stdout [punk::ansi::vt52 cursor_off]
}
}
}
}
@ -2858,10 +3080,20 @@ namespace eval punk::console {
}
}
}
}
proc move_up {n} {
proc move_up {n} {
puts -nonewline stdout [punk::ansi::move_up $n]
upvar ::punk::console::is_vt52 is_vt52
if {!$is_vt52} {
puts -nonewline stdout [punk::ansi::move_up $n]
} else {
puts -nonewline stdout [punk::ansi::vt52move_up $n]
}
}
}
proc move_down {n} {
proc move_down {n} {
puts -nonewline stdout [punk::ansi::move_down $n]
upvar ::punk::console::is_vt52 is_vt52
if {!$is_vt52} {
puts -nonewline stdout [punk::ansi::move_down $n]
} else {
puts -nonewline stdout [punk::ansi::vt52move_down $n]
}
}
}
proc move_column {col} {
proc move_column {col} {
upvar ::punk::console::is_vt52 is_vt52
upvar ::punk::console::is_vt52 is_vt52
@ -2925,12 +3157,12 @@ namespace eval punk::console {
}
}
append commands [punk::ansi::cursor_restore_dec]
append commands [punk::ansi::cursor_restore_dec]
} else {
} else {
append commands [punk::ansi::cursor_save_vt52 ]
append commands [punk::ansi::vt52 cursor_save]
append commands [punk::ansi::vt52move_emit $row $col $data]
append commands [punk::ansi::vt52move_emit $row $col $data]
foreach {row col data} $args {
foreach {row col data} $args {
append commands [punk::ansi::vt52move_emit $row $col $data]
append commands [punk::ansi::vt52move_emit $row $col $data]
}
}
append commands [punk::ansi::cursor_restore_vt52 ]
append commands [punk::ansi::vt52 cursor_restore]
}
}
puts -nonewline stdout $commands; flush stdout
puts -nonewline stdout $commands; flush stdout
}
}
@ -2945,12 +3177,12 @@ namespace eval punk::console {
}
}
append commands [punk::ansi::cursor_restore_dec]
append commands [punk::ansi::cursor_restore_dec]
} else {
} else {
append commands [punk::ansi::cursor_save_vt52 ]
append commands [punk::ansi::vt52 cursor_save]
foreach ln [split $textblock \n] {
foreach ln [split $textblock \n] {
append commands [punk::ansi::vt52move_emit $row $col $ln]
append commands [punk::ansi::vt52move_emit $row $col $ln]
incr row
incr row
}
}
append commands [punk::ansi::cursor_restore_vt52 ]
append commands [punk::ansi::vt52 cursor_restore]
}
}
puts -nonewline stdout $commands;flush stdout
puts -nonewline stdout $commands;flush stdout
return
return