summaryrefslogtreecommitdiff
path: root/example/xkibitz
diff options
context:
space:
mode:
Diffstat (limited to 'example/xkibitz')
-rwxr-xr-xexample/xkibitz219
1 files changed, 219 insertions, 0 deletions
diff --git a/example/xkibitz b/example/xkibitz
new file mode 100755
index 0000000..b61a22f
--- /dev/null
+++ b/example/xkibitz
@@ -0,0 +1,219 @@
+#!/bin/sh
+# -*- tcl -*-
+# The next line is executed by /bin/sh, but not tcl \
+exec tclsh "$0" ${1+"$@"}
+
+package require Expect
+
+
+# share an xterm with other users
+# See xkibitz(1) man page for complete info.
+# Compare with kibitz.
+# Author: Don Libes, NIST
+# Version: 1.2
+
+proc help {} {
+ puts "Commands Meaning"
+ puts "-------- -------"
+ puts "return return to program"
+ puts "= list"
+ puts "+ <display> add"
+ puts "- <tag> drop"
+ puts "where <display> is an X display name such as nist.gov or nist.gov:0.0"
+ puts "and <tag> is a tag from the = command."
+ puts "+ and - require whitespace before argument."
+ puts {return command must be spelled out ("r", "e", "t", ...).}
+}
+
+proc prompt1 {} {
+ return "xkibitz> "
+}
+
+proc h {} help
+proc ? {} help
+
+# disable history processing - there seems to be some incestuous relationship
+# between history and unknown in Tcl 8.0
+proc history {args} {}
+proc unknown {args} {
+ puts "$args: invalid command"
+ help
+}
+
+set tag2pid(0) [pid]
+set pid2tty([pid]) "/dev/tty"
+if {[info exists env(DISPLAY)]} {
+ set pid2display([pid]) $env(DISPLAY)
+} else {
+ set pid2display([pid]) ""
+}
+
+# small int allowing user to more easily identify display
+# maxtag always points at highest in use
+set maxtag 0
+
+proc + {display} {
+ global ids pid2display pid2tag tag2pid maxtag pid2sid
+ global pid2tty env
+
+ if {![string match *:* $display]} {
+ append display :0.0
+ }
+
+ if {![info exists env(XKIBITZ_XTERM_ARGS)]} {
+ set env(XKIBITZ_XTERM_ARGS) ""
+ }
+
+ set dummy1 [open /dev/null]
+ set dummy2 [open /dev/null]
+ spawn -pty -noecho
+ close $dummy1
+ close $dummy2
+
+ stty raw -echo < $spawn_out(slave,name)
+ # Linux needs additional stty, sounds like a bug in its stty to me.
+ # raw should imply this stuff, no?
+ stty -icrnl -icanon < $spawn_out(slave,name)
+
+ regexp ".*(.)(.)" $spawn_out(slave,name) dummy c1 c2
+ if {[string compare $c1 "/"] == 0} {
+ # On Pyramid and AIX, ttynames such as /dev/pts/1
+ # requre suffix to be padded with a 0
+ set c1 0
+ }
+
+ set pid [eval exec xterm \
+ -display $display \
+ -geometry [stty columns]x[stty rows] \
+ -S$c1$c2$spawn_out(slave,fd) \
+ $env(XKIBITZ_XTERM_ARGS) &]
+ close -slave
+
+ # xterm first sends back window id, discard
+ log_user 0
+ expect {
+ eof {wait;return}
+ \n
+ }
+ log_user 1
+
+ lappend ids $spawn_id
+ set pid2display($pid) $display
+ incr maxtag
+ set tag2pid($maxtag) $pid
+ set pid2tag($pid) $maxtag
+ set pid2sid($pid) $spawn_id
+ set pid2tty($pid) $spawn_out(slave,name)
+ return
+}
+
+proc = {} {
+ global pid2display tag2pid pid2tty
+
+ puts "Tag Size Display"
+ foreach tag [lsort -integer [array names tag2pid]] {
+ set pid $tag2pid($tag)
+ set tty $pid2tty($pid)
+
+ puts [format "%3d [stty columns < $tty]x[stty rows < $tty] $pid2display($pid)" $tag]
+ }
+}
+
+proc - {tag} {
+ global tag2pid pid2tag pid2display maxtag ids pid2sid
+ global pid2tty
+
+ if {![info exists tag2pid($tag)]} {
+ puts "no such tag"
+ return
+ }
+ if {$tag == 0} {
+ puts "cannot drop self"
+ return
+ }
+
+ set pid $tag2pid($tag)
+
+ # close and remove spawn_id from list
+ set spawn_id $pid2sid($pid)
+ set index [lsearch $ids $spawn_id]
+ set ids [lreplace $ids $index $index]
+
+ exec kill -9 $pid
+ close
+ wait
+
+ unset tag2pid($tag)
+ unset pid2tag($pid)
+ unset pid2display($pid)
+ unset pid2sid($pid)
+ unset pid2tty($pid)
+
+ # lower maxtag if possible
+ while {![info exists tag2pid($maxtag)]} {
+ incr maxtag -1
+ }
+}
+
+rename exit exitReal
+
+proc exit {} {
+ global pid2display
+
+ unset pid2display([pid]) ;# avoid killing self
+
+ foreach pid [array names pid2display] {
+ catch {exec kill -9 $pid}
+ }
+ exitReal
+}
+
+trap exit HUP
+
+trap {
+ set r [stty rows]
+ set c [stty columns]
+ stty rows $r columns $c < $app_tty
+ foreach pid [array names pid2tty] {
+ if {$pid == [pid]} continue
+ stty rows $r columns $c < $pid2tty($pid)
+ }
+} WINCH
+
+set escape \035 ;# control-right-bracket
+set escape_printable "^\]"
+
+while {[llength $argv]>0} {
+ set flag [lindex $argv 0]
+ switch -- $flag \
+ "-escape" {
+ set escape [lindex $argv 1]
+ set escape_printable $escape
+ set argv [lrange $argv 2 end]
+ } "-display" {
+ + [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } default {
+ break
+ }
+}
+
+if {[llength $argv]>0} {
+ eval spawn -noecho $argv
+} else {
+ spawn -noecho $env(SHELL)
+}
+set prog $spawn_id
+set app_tty $spawn_out(slave,name)
+
+puts "Escape sequence is $escape_printable"
+
+interact {
+ -input $user_spawn_id -reset $escape {
+ puts "\nfor help enter: ? or h or help"
+ interpreter -eof exit
+ } -output $prog
+ -input ids -output $prog
+ -input $prog eof exit -output $user_spawn_id -output ids
+}
+