summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/tk
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-11-01 06:45:43 +0000
committerpeter <peter@FreeBSD.org>1996-11-01 06:45:43 +0000
commit59cc89c2c2e686da3bdab2d5cfac4f33462d29fe (patch)
tree88f923c9c0be2e2a225a9b21716fd582de668b42 /contrib/nvi/tk
downloadFreeBSD-src-59cc89c2c2e686da3bdab2d5cfac4f33462d29fe.zip
FreeBSD-src-59cc89c2c2e686da3bdab2d5cfac4f33462d29fe.tar.gz
Import of nvi-1.79, minus a few bits that we dont need (eg: postscript
files, curses, db, regex etc that we already have). The other glue will follow shortly. Obtained from: Keith Bostic <bostic@bostic.com>
Diffstat (limited to 'contrib/nvi/tk')
-rw-r--r--contrib/nvi/tk/init.tcl1096
-rw-r--r--contrib/nvi/tk/tk_funcs.c346
-rw-r--r--contrib/nvi/tk/tk_main.c423
-rw-r--r--contrib/nvi/tk/tk_read.c207
-rw-r--r--contrib/nvi/tk/tk_screen.c86
-rw-r--r--contrib/nvi/tk/tk_term.c169
-rw-r--r--contrib/nvi/tk/tk_util.c250
-rw-r--r--contrib/nvi/tk/tki.h64
8 files changed, 2641 insertions, 0 deletions
diff --git a/contrib/nvi/tk/init.tcl b/contrib/nvi/tk/init.tcl
new file mode 100644
index 0000000..78c5a11
--- /dev/null
+++ b/contrib/nvi/tk/init.tcl
@@ -0,0 +1,1096 @@
+# @(#)init.tcl 8.10 (Berkeley) 7/19/96
+proc screen {} {
+ global tk_ssize_row
+ global tk_ssize_col
+
+ # Build menubar with File, Options and Help entries.
+ frame .menu -relief raised -borderwidth 1
+ pack append . .menu {top fillx}
+
+ # File pull-down menu
+ menubutton .menu.file -text "File" \
+ -menu .menu.file.fileops -underline 0
+ menu .menu.file.fileops
+ .menu.file.fileops add command -label "Edit ..." \
+ -command "tk_edit" -underline 0
+ .menu.file.fileops add command -label "Save File" \
+ -command "tk_write" -underline 0
+ .menu.file.fileops add command -label "Save File as ..." \
+ -command "tk_writeas" -underline 1
+ .menu.file.fileops add command -label "Save and Quit" \
+ -command "tk_writequit" -underline 7
+ .menu.file.fileops add command -label "Quit" \
+ -command "tk_quit" -underline 0
+
+ # Options pull-down menu
+ menubutton .menu.option -text "Options" \
+ -menu .menu.option.optionops -underline 0
+ menu .menu.option.optionops
+ .menu.option.optionops add command -label "Set all" \
+ -command tk_options -underline 0
+
+ # Help pull-down menu
+ menubutton .menu.help -text "Help" \
+ -menu .menu.help.helpops -underline 0
+ menu .menu.help.helpops
+ .menu.help.helpops add command -label "On Help" -underline 3 \
+ -command tk_help
+ .menu.help.helpops add command -label "On Version" -underline 3 \
+ -command tk_version
+
+ pack append .menu \
+ .menu.file {left} .menu.option {left} .menu.help {right}
+
+ # Set up for keyboard-based menu traversal
+ tk_bindForTraversal .
+ bind . <Any-Enter> {focus .}
+ focus .
+ tk_menuBar .menu .menu.file .menu.help
+
+ # Create text window
+ text .t -relief raised -bd 1 -setgrid true -yscrollcommand ".s set"
+ scrollbar .s -relief flat -command ".t yview"
+ pack append . .s {right filly} .t {expand fill}
+
+ # Use tags to build a cursor for the text window.
+ set bg [lindex [.t config -background] 4]
+ set fg [lindex [.t config -foreground] 4]
+ .t tag configure tk_cursor -background $fg -foreground $bg
+ .t mark set tk_cursor_indx insert
+ .t tag add tk_cursor tk_cursor_indx
+
+ # Bind the keys.
+ bind .t <Any-KeyPress> {tk_flash; break}
+ bind .t 0 {tk_key_enter "0"; break}
+ bind .t 1 {tk_key_enter "1"; break}
+ bind .t 2 {tk_key_enter "2"; break}
+ bind .t 3 {tk_key_enter "3"; break}
+ bind .t 4 {tk_key_enter "4"; break}
+ bind .t 5 {tk_key_enter "5"; break}
+ bind .t 6 {tk_key_enter "6"; break}
+ bind .t 7 {tk_key_enter "7"; break}
+ bind .t 8 {tk_key_enter "8"; break}
+ bind .t 9 {tk_key_enter "9"; break}
+ bind .t <BackSpace> {tk_key_enter "\010"; break}
+ bind .t <Control-a> {tk_key_enter "\001"; break}
+ bind .t <Control-b> {tk_key_enter "\002"; break}
+ bind .t <Control-c> {tk_key_enter "\003"; break}
+ bind .t <Control-d> {tk_key_enter "\004"; break}
+ bind .t <Control-e> {tk_key_enter "\005"; break}
+ bind .t <Control-f> {tk_key_enter "\006"; break}
+ bind .t <Control-g> {tk_key_enter "\007"; break}
+ bind .t <Control-h> {tk_key_enter "\010"; break}
+ bind .t <Control-i> {tk_key_enter "\011"; break}
+ bind .t <Control-j> {tk_key_enter "\012"; break}
+ bind .t <Control-k> {tk_key_enter "\013"; break}
+ bind .t <Control-l> {tk_key_enter "\014"; break}
+ bind .t <Control-m> {tk_key_enter "\015"; break}
+ bind .t <Control-n> {tk_key_enter "\016"; break}
+ bind .t <Control-o> {tk_key_enter "\017"; break}
+ bind .t <Control-p> {tk_key_enter "\020"; break}
+ bind .t <Control-q> {tk_key_enter "\021"; break}
+ bind .t <Control-r> {tk_key_enter "\022"; break}
+ bind .t <Control-s> {tk_key_enter "\023"; break}
+ bind .t <Control-t> {tk_key_enter "\024"; break}
+ bind .t <Control-u> {tk_key_enter "\025"; break}
+ bind .t <Control-v> {tk_key_enter "\026"; break}
+ bind .t <Control-w> {tk_key_enter "\027"; break}
+ bind .t <Control-x> {tk_key_enter "\030"; break}
+ bind .t <Control-y> {tk_key_enter "\031"; break}
+ bind .t <Control-z> {tk_key_enter "\032"; break}
+ bind .t <Control_L> {tk_noop; break}
+ bind .t <Control_R> {tk_noop; break}
+ bind .t <Delete> {tk_key_enter "x"; break}
+ bind .t <Down> {tk_key_enter "j"; break}
+ bind .t <End> {tk_key_enter "G"; break}
+ bind .t <Escape> {tk_key_enter "\033"; break}
+ bind .t <Home> {tk_key_enter "1G"; break}
+ bind .t <Insert> {tk_key_enter "i"; break}
+ bind .t <Left> {tk_key_enter "h"; break}
+ bind .t <Next> {tk_key_enter "\006"; break}
+ bind .t <Prior> {tk_key_enter "\002"; break}
+ bind .t <Return> {tk_key_enter "\015"; break}
+ bind .t <Right> {tk_key_enter "l"; break}
+ bind .t <Shift_L> {tk_noop; break}
+ bind .t <Shift_Lock> {tk_noop; break}
+ bind .t <Shift_R> {tk_noop; break}
+ bind .t <Tab> {tk_key_enter "\011"; break}
+ bind .t <Up> {tk_key_enter "k"; break}
+ bind .t <ampersand> {tk_key_enter "&"; break}
+ bind .t <asciicircum> {tk_key_enter "^"; break}
+ bind .t <asciitilde> {tk_key_enter "~"; break}
+ bind .t <asterisk> {tk_key_enter "*"; break}
+ bind .t <at> {tk_key_enter "@"; break}
+ bind .t <backslash> {tk_key_enter "\\"; break}
+ bind .t <bar> {tk_key_enter "|"; break}
+ bind .t <braceleft> {tk_key_enter "{"; break}
+ bind .t <braceright> {tk_key_enter "; break}"}
+ bind .t <bracketleft> {tk_key_enter "\["; break}
+ bind .t <bracketright> {tk_key_enter "]"; break}
+ bind .t <colon> {tk_key_enter ":"; break}
+ bind .t <comma> {tk_key_enter ","; break}
+ bind .t <dollar> {tk_key_enter "$"; break}
+ bind .t <equal> {tk_key_enter "="; break}
+ bind .t <exclam> {tk_key_enter "!"; break}
+ bind .t <greater> {tk_key_enter ">"; break}
+ bind .t <less> {tk_key_enter "<"; break}
+ bind .t <minus> {tk_key_enter "-"; break}
+ bind .t <numbersign> {tk_key_enter "#"; break}
+ bind .t <parenleft> {tk_key_enter "("; break}
+ bind .t <parenright> {tk_key_enter ")"; break}
+ bind .t <percent> {tk_key_enter "%"; break}
+ bind .t <period> {tk_key_enter "."; break}
+ bind .t <plus> {tk_key_enter "+"; break}
+ bind .t <question> {tk_key_enter "?"; break}
+ bind .t <quotedbl> {tk_key_enter "\""; break}
+ bind .t <quoteright> {tk_key_enter "'"; break}
+ bind .t <semicolon> {tk_key_enter ";"; break}
+ bind .t <slash> {tk_key_enter "/"; break}
+ bind .t <space> {tk_key_enter " "; break}
+ bind .t <underscore> {tk_key_enter "_"; break}
+ bind .t A {tk_key_enter "A"; break}
+ bind .t B {tk_key_enter "B"; break}
+ bind .t C {tk_key_enter "C"; break}
+ bind .t D {tk_key_enter "D"; break}
+ bind .t E {tk_key_enter "E"; break}
+ bind .t F {tk_key_enter "F"; break}
+ bind .t G {tk_key_enter "G"; break}
+ bind .t H {tk_key_enter "H"; break}
+ bind .t I {tk_key_enter "I"; break}
+ bind .t J {tk_key_enter "J"; break}
+ bind .t K {tk_key_enter "K"; break}
+ bind .t L {tk_key_enter "L"; break}
+ bind .t M {tk_key_enter "M"; break}
+ bind .t N {tk_key_enter "N"; break}
+ bind .t O {tk_key_enter "O"; break}
+ bind .t P {tk_key_enter "P"; break}
+ bind .t Q {tk_key_enter "Q"; break}
+ bind .t R {tk_key_enter "R"; break}
+ bind .t S {tk_key_enter "S"; break}
+ bind .t T {tk_key_enter "T"; break}
+ bind .t U {tk_key_enter "U"; break}
+ bind .t V {tk_key_enter "V"; break}
+ bind .t W {tk_key_enter "W"; break}
+ bind .t X {tk_key_enter "X"; break}
+ bind .t Y {tk_key_enter "Y"; break}
+ bind .t Z {tk_key_enter "Z"; break}
+ bind .t a {tk_key_enter "a"; break}
+ bind .t b {tk_key_enter "b"; break}
+ bind .t c {tk_key_enter "c"; break}
+ bind .t d {tk_key_enter "d"; break}
+ bind .t e {tk_key_enter "e"; break}
+ bind .t f {tk_key_enter "f"; break}
+ bind .t g {tk_key_enter "g"; break}
+ bind .t h {tk_key_enter "h"; break}
+ bind .t i {tk_key_enter "i"; break}
+ bind .t j {tk_key_enter "j"; break}
+ bind .t k {tk_key_enter "k"; break}
+ bind .t l {tk_key_enter "l"; break}
+ bind .t m {tk_key_enter "m"; break}
+ bind .t n {tk_key_enter "n"; break}
+ bind .t o {tk_key_enter "o"; break}
+ bind .t p {tk_key_enter "p"; break}
+ bind .t q {tk_key_enter "q"; break}
+ bind .t r {tk_key_enter "r"; break}
+ bind .t s {tk_key_enter "s"; break}
+ bind .t t {tk_key_enter "t"; break}
+ bind .t u {tk_key_enter "u"; break}
+ bind .t v {tk_key_enter "v"; break}
+ bind .t w {tk_key_enter "w"; break}
+ bind .t x {tk_key_enter "x"; break}
+ bind .t y {tk_key_enter "y"; break}
+ bind .t z {tk_key_enter "z"; break}
+
+ # XXX
+ # I haven't been able to make Tcl/Tk write uninitialized portions
+ # of the text window. Fill in the screen.
+ tk_ssize
+ .t mark set insert 1.0
+ for {set i 1} {$i <= $tk_ssize_row} {incr i} {
+ for {set j 1} {$j <= $tk_ssize_col} {incr j} {
+ .t insert insert " "
+ }
+ .t insert insert "\n"
+ }
+}
+
+# tk_noop --
+# Do nothing.
+#
+# XXX
+# I can't figure out how to get a binding that does nothing without
+# calling a function, so this stub does it for me.
+proc tk_noop {} {
+}
+
+# tk_key_enter --
+# Enter a key.
+proc tk_key_enter {val} {
+ global newkey
+ global waiting
+
+ set waiting 0
+ tk_key $val
+ set newkey 1
+}
+
+# tk_key_wait --
+# Wait for a key.
+proc tk_key_wait {timeout} {
+ global newkey
+ global waiting
+
+ if { $timeout != 0 } {
+ after $timeout "set newkey 1"
+ }
+ set waiting 1
+ tkwait variable newkey
+}
+
+# Callback functions for the File menu.
+# tk_edit
+# Edit another file.
+proc tk_edit {} {
+}
+
+# tk_quit
+# Quit.
+proc tk_quit {} {
+ global newkey
+ global waiting
+
+ tk_op quit
+ if { $waiting != 0 } {
+ set newkey 1
+ }
+}
+
+# tk_write
+# Write the edit buffer.
+proc tk_write {} {
+ global newkey
+ global waiting
+
+ tk_op write
+ if { $waiting != 0 } {
+ set newkey 1
+ }
+}
+
+# tk_writeas
+# Write the edit buffer to a named file.
+proc tk_writeas {} {
+}
+
+# tk_writequit
+# Write and quit.
+proc tk_writequit {} {
+ global newkey
+ global waiting
+
+ tk_op writequit
+ if { $waiting != 0 } {
+ set newkey 1
+ }
+}
+
+# Callback functions for the Help menu.
+#
+# tk_help --
+# Present a help screen.
+proc tk_help {} {
+ tk_dialog .d {} "No help screen currently available." {} 0 Continue
+}
+
+# tk_options
+# Contains the option selector box. It is divided into three parts, the
+# checkbuttons for the boolean options, the entry fields for the string
+# numeric options, and a control area containing buttons. There is only
+# one function.
+proc tk_options {} {
+
+ # Build option selector box with three subframes for boolean,
+ # numeric, and string options. Make it a toplevel window.
+ toplevel .os
+ wm title .os options
+
+ # Option variables.
+ global tko_altwerase
+ global tko_autoindent
+ global tko_autoprint
+ global tko_autowrite
+ global tko_backup
+ global tko_beautify
+ global tko_cdpath
+ global tko_cedit
+ global tko_columns
+ global tko_comment
+ global tko_directory
+ global tko_edcompatible
+ global tko_escapetime
+ global tko_errorbells
+ global tko_exrc
+ global tko_extended
+ global tko_filec
+ global tko_flash
+ global tko_hardtabs
+ global tko_iclower
+ global tko_ignorecase
+ global tko_keytime
+ global tko_leftright
+ global tko_lines
+ global tko_lisp
+ global tko_list
+ global tko_lock
+ global tko_magic
+ global tko_matchtime
+ global tko_mesg
+ global tko_modeline
+ global tko_msgcat
+ global tko_noprint
+ global tko_number
+ global tko_octal
+ global tko_open
+ global tko_optimize
+ global tko_paragraphs
+ global tko_print
+ global tko_prompt
+ global tko_readonly
+ global tko_recdir
+ global tko_redraw
+ global tko_remap
+ global tko_report
+ global tko_ruler
+ global tko_scroll
+ global tko_searchincr
+ global tko_sections
+ global tko_secure
+ global tko_shell
+ global tko_shellmeta
+ global tko_shiftwidth
+ global tko_showmatch
+ global tko_showmode
+ global tko_sidescroll
+ global tko_slowopen
+ global tko_sourceany
+ global tko_tabstop
+ global tko_taglength
+ global tko_tags
+ global tko_term
+ global tko_terse
+ global tko_tildeop
+ global tko_timeout
+ global tko_ttywerase
+ global tko_verbose
+ global tko_warn
+ global tko_window
+ global tko_windowname
+ global tko_wraplen
+ global tko_wrapmargin
+ global tko_wrapscan
+ global tko_writeany
+
+ # Initialize option values.
+ tk_opt_init
+
+ # Build subframe for boolean options.
+ frame .os.bopts
+
+ # This is the width of the edcompatible button.
+ set buttonwidth 13
+
+ # Pack the boolean os, 5 to a frame.
+ frame .os.bopts.f1
+ pack append .os.bopts .os.bopts.f1 {top}
+ checkbutton .os.bopts.f1.b1 \
+ -variable tko_altwerase -text "altwerase" \
+ -command "tk_opt_set altwerase $tko_altwerase" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f1.b2 \
+ -variable tko_autoindent -text "autoindent" \
+ -command "tk_opt_set autoindent $tko_autoindent" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f1.b3 \
+ -variable tko_autoprint -text "autoprint" \
+ -command "tk_opt_set autoprint $tko_autoprint" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f1.b4 \
+ -variable tko_autowrite -text "autowrite" \
+ -command "tk_opt_set autowrite $tko_autowrite" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f1.b5 \
+ -variable tko_beautify -text "beautify" \
+ -command "tk_opt_set beautify $tko_beautify" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f1 \
+ .os.bopts.f1.b1 {left frame w} \
+ .os.bopts.f1.b2 {left frame w} \
+ .os.bopts.f1.b3 {left frame w} \
+ .os.bopts.f1.b4 {left frame w} \
+ .os.bopts.f1.b5 {left frame w}
+
+ frame .os.bopts.f2
+ pack append .os.bopts .os.bopts.f2 {top}
+ checkbutton .os.bopts.f2.b1 \
+ -variable tko_comment -text "comment" \
+ -command "tk_opt_set comment $tko_comment" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f2.b2 \
+ -variable tko_edcompatible -text "edcompatible" \
+ -command "tk_opt_set edcompatible $tko_edcompatible" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f2.b3 \
+ -variable tko_errorbells -text "errorbells" \
+ -command "tk_opt_set errorbells $tko_errorbells" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f2.b4 \
+ -variable tko_exrc -text "exrc" \
+ -command "tk_opt_set exrc $tko_exrc" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f2.b5 \
+ -variable tko_extended -text "extended" \
+ -command "tk_opt_set extended $tko_extended" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f2 \
+ .os.bopts.f2.b1 {left frame w} \
+ .os.bopts.f2.b2 {left frame w} \
+ .os.bopts.f2.b3 {left frame w} \
+ .os.bopts.f2.b4 {left frame w} \
+ .os.bopts.f2.b5 {left frame w}
+
+ frame .os.bopts.f3
+ pack append .os.bopts .os.bopts.f3 {top}
+ checkbutton .os.bopts.f3.b1 \
+ -variable tko_flash -text "flash" \
+ -command "tk_opt_set flash $tko_flash" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f3.b2 \
+ -variable tko_iclower -text "iclower" \
+ -command "tk_opt_set iclower $tko_iclower" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f3.b3 \
+ -variable tko_ignorecase -text "ignorecase" \
+ -command "tk_opt_set ignorecase $tko_ignorecase" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f3.b4 \
+ -variable tko_leftright -text "leftright" \
+ -command "tk_opt_set leftright $tko_leftright" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f3.b5 \
+ -variable tko_lisp -text "lisp" \
+ -command "tk_opt_set lisp $tko_lisp" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f3 \
+ .os.bopts.f3.b1 {left frame w} \
+ .os.bopts.f3.b2 {left frame w} \
+ .os.bopts.f3.b3 {left frame w} \
+ .os.bopts.f3.b4 {left frame w} \
+ .os.bopts.f3.b5 {left frame w}
+
+ frame .os.bopts.f4
+ pack append .os.bopts .os.bopts.f4 {top}
+ checkbutton .os.bopts.f4.b1 \
+ -variable tko_list -text "list" \
+ -command "tk_opt_set list $tko_list" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f4.b2 \
+ -variable tko_lock -text "lock" \
+ -command "tk_opt_set lock $tko_lock" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f4.b3 \
+ -variable tko_magic -text "magic" \
+ -command "tk_opt_set magic $tko_magic" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f4.b4 \
+ -variable tko_mesg -text "mesg" \
+ -command "tk_opt_set mesg $tko_mesg" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f4.b5\
+ -variable tko_number -text "number" \
+ -command "tk_opt_set number $tko_number" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f4 \
+ .os.bopts.f4.b1 {left frame w} \
+ .os.bopts.f4.b2 {left frame w} \
+ .os.bopts.f4.b3 {left frame w} \
+ .os.bopts.f4.b4 {left frame w} \
+ .os.bopts.f4.b5 {left frame w}
+
+ frame .os.bopts.f5
+ pack append .os.bopts .os.bopts.f5 {top}
+ checkbutton .os.bopts.f5.b1 \
+ -variable tko_octal -text "octal" \
+ -command "tk_opt_set octal $tko_octal" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f5.b2 \
+ -variable tko_open -text "open" \
+ -command "tk_opt_set open $tko_open" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f5.b3 \
+ -variable tko_optimize -text "optimize" \
+ -command "tk_opt_set optimize $tko_optimize" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f5.b4 \
+ -variable tko_prompt -text "prompt" \
+ -command "tk_opt_set prompt $tko_prompt" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f5.b5 \
+ -variable tko_readonly -text "readonly" \
+ -command "tk_opt_set readonly $tko_readonly" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f5 \
+ .os.bopts.f5.b1 {left frame w} \
+ .os.bopts.f5.b2 {left frame w} \
+ .os.bopts.f5.b3 {left frame w} \
+ .os.bopts.f5.b4 {left frame w} \
+ .os.bopts.f5.b5 {left frame w}
+
+ frame .os.bopts.f6
+ pack append .os.bopts .os.bopts.f6 {top}
+ checkbutton .os.bopts.f6.b1 \
+ -variable tko_remap -text "remap" \
+ -command "tk_opt_set remap $tko_remap" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f6.b2 \
+ -variable tko_ruler -text "ruler" \
+ -command "tk_opt_set ruler $tko_ruler" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f6.b3 \
+ -variable tko_searchincr -text "searchincr" \
+ -command "tk_opt_set searchincr $tko_searchincr" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f6.b4 \
+ -variable tko_secure -text "secure" \
+ -command "tk_opt_set secure $tko_secure" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f6.b5 \
+ -variable tko_showmatch -text "showmatch" \
+ -command "tk_opt_set showmatch $tko_showmatch" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f6 \
+ .os.bopts.f6.b1 {left frame w} \
+ .os.bopts.f6.b2 {left frame w} \
+ .os.bopts.f6.b3 {left frame w} \
+ .os.bopts.f6.b4 {left frame w} \
+ .os.bopts.f6.b5 {left frame w}
+
+ frame .os.bopts.f7
+ pack append .os.bopts .os.bopts.f7 {top}
+ checkbutton .os.bopts.f7.b1 \
+ -variable tko_showmode -text "showmode" \
+ -command "tk_opt_set showmode $tko_showmode" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f7.b2 \
+ -variable tko_slowopen -text "slowopen" \
+ -command "tk_opt_set slowopen $tko_slowopen" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f7.b3 \
+ -variable tko_sourceany -text "sourceany" \
+ -command "tk_opt_set sourceany $tko_sourceany" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f7.b4 \
+ -variable tko_terse -text "terse" \
+ -command "tk_opt_set terse $tko_terse" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f7.b5 \
+ -variable tko_tildeop -text "tildeop" \
+ -command "tk_opt_set tildeope $tko_tildeop" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f7 \
+ .os.bopts.f7.b1 {left frame w} \
+ .os.bopts.f7.b2 {left frame w} \
+ .os.bopts.f7.b3 {left frame w} \
+ .os.bopts.f7.b4 {left frame w} \
+ .os.bopts.f7.b5 {left frame w}
+
+ frame .os.bopts.f8
+ pack append .os.bopts .os.bopts.f8 {top fillx}
+ checkbutton .os.bopts.f8.b1 \
+ -variable tko_timeout -text "timeout" \
+ -command "tk_opt_set timeout $tko_timeout" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f8.b2 \
+ -variable tko_ttywerase -text "ttywerase" \
+ -command "tk_opt_set ttywerase $tko_ttywerase" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f8.b3 \
+ -variable tko_verbose -text "verbose" \
+ -command "tk_opt_set verbose $tko_verbose" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f8.b4 \
+ -variable tko_warn -text "warn" \
+ -command "tk_opt_set warn $tko_warn" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f8.b5 \
+ -variable tko_windowname -text "windowname" \
+ -command "tk_opt_set windowname $tko_windowname" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f8 \
+ .os.bopts.f8.b1 {left frame w} \
+ .os.bopts.f8.b2 {left frame w} \
+ .os.bopts.f8.b3 {left frame w} \
+ .os.bopts.f8.b4 {left frame w} \
+ .os.bopts.f8.b5 {left frame w}
+
+ frame .os.bopts.f9
+ pack append .os.bopts .os.bopts.f9 {top fillx}
+ checkbutton .os.bopts.f9.b1 \
+ -variable tko_wrapscan -text "wrapscan" \
+ -command "tk_opt_set wrapscan $tko_wrapscan" \
+ -width $buttonwidth -anchor w
+ checkbutton .os.bopts.f9.b2 \
+ -variable tko_writeany -text "writeany" \
+ -command "tk_opt_set writeany $tko_writeany" \
+ -width $buttonwidth -anchor w
+ pack append .os.bopts.f9 \
+ .os.bopts.f9.b1 {left frame w} \
+ .os.bopts.f9.b2 {left frame w}
+
+ # Build frame for number options:
+ frame .os.nopts
+
+ # Label and entry widths.
+ set lwidth 12
+ set ewidth 3
+
+ frame .os.nopts.n1
+ label .os.nopts.n1.l -text "column:" -width $lwidth -anchor w
+ entry .os.nopts.n1.e -width $ewidth -relief raised \
+ -textvariable tko_columns
+ trace variable tko_columns w tk_opt_ew
+ pack append .os.nopts.n1 \
+ .os.nopts.n1.l {left} .os.nopts.n1.e {left frame w}
+
+ frame .os.nopts.n2
+ label .os.nopts.n2.l -text "escapetime:" -width $lwidth -anchor w
+ entry .os.nopts.n2.e -width $ewidth -textvariable tko_escapetime \
+ -relief raised
+ trace variable tko_escapetime w tk_opt_ew
+ pack append .os.nopts.n2 \
+ .os.nopts.n2.l {left} .os.nopts.n2.e {left frame w}
+
+ frame .os.nopts.n3
+ label .os.nopts.n3.l -text "hardtabs:" -width $lwidth -anchor w
+ entry .os.nopts.n3.e -width $ewidth -textvariable tko_hardtabs \
+ -relief raised
+ trace variable tko_hardtabs w tk_opt_ew
+ pack append .os.nopts.n3 \
+ .os.nopts.n3.l {left} .os.nopts.n3.e {left frame w}
+
+ frame .os.nopts.n4
+ label .os.nopts.n4.l -text "keytime:" -width $lwidth -anchor w
+ entry .os.nopts.n4.e -width $ewidth -textvariable tko_keytime \
+ -relief raised
+ trace variable tko_keytime w tk_opt_ew
+ pack append .os.nopts.n4 \
+ .os.nopts.n4.l {left} .os.nopts.n4.e {left frame w}
+
+ frame .os.nopts.n5
+ label .os.nopts.n5.l -text "lines:" -width $lwidth -anchor w
+ entry .os.nopts.n5.e -width $ewidth -textvariable tko_lines \
+ -relief raised
+ trace variable tko_lines w tk_opt_ew
+ pack append .os.nopts.n5 \
+ .os.nopts.n5.l {left} .os.nopts.n5.e {left frame w}
+
+ frame .os.nopts.n6
+ label .os.nopts.n6.l -text "matchtime:" -width $lwidth -anchor w
+ entry .os.nopts.n6.e -width $ewidth -textvariable tko_matchtime \
+ -relief raised
+ trace variable tko_matchtime w tk_opt_ew
+ pack append .os.nopts.n6 \
+ .os.nopts.n6.l {left} .os.nopts.n6.e {left frame w}
+
+ frame .os.nopts.n7
+ label .os.nopts.n7.l -text "report:" -width $lwidth -anchor w
+ entry .os.nopts.n7.e -width $ewidth -textvariable tko_report \
+ -relief raised
+ trace variable tko_report w tk_opt_ew
+ pack append .os.nopts.n7 \
+ .os.nopts.n7.l {left} .os.nopts.n7.e {left frame w}
+
+ frame .os.nopts.n8
+ label .os.nopts.n8.l -text "scroll:" -width $lwidth -anchor w
+ entry .os.nopts.n8.e -width $ewidth -textvariable tko_scroll \
+ -relief raised
+ trace variable tko_scroll w tk_opt_ew
+ pack append .os.nopts.n8 \
+ .os.nopts.n8.l {left} .os.nopts.n8.e {left frame w}
+
+ frame .os.nopts.n9
+ label .os.nopts.n9.l -text "shiftwidth:" -width $lwidth -anchor w
+ entry .os.nopts.n9.e -width $ewidth -textvariable tko_shiftwidth \
+ -relief raised
+ trace variable tko_shiftwidth w tk_opt_ew
+ pack append .os.nopts.n9 \
+ .os.nopts.n9.l {left} .os.nopts.n9.e {left frame w}
+
+ frame .os.nopts.n10
+ label .os.nopts.n10.l -text "sidescroll:" -width $lwidth -anchor w
+ entry .os.nopts.n10.e -width $ewidth -textvariable tko_sidescroll \
+ -relief raised
+ trace variable tko_sidescroll w tk_opt_ew
+ pack append .os.nopts.n10 \
+ .os.nopts.n10.l {left} .os.nopts.n10.e {left frame w}
+
+ frame .os.nopts.n11
+ label .os.nopts.n11.l -text "tabstop:" -width $lwidth -anchor w
+ entry .os.nopts.n11.e -width $ewidth -textvariable tko_tabstop \
+ -relief raised
+ trace variable tko_tabstop w tk_opt_ew
+ pack append .os.nopts.n11 \
+ .os.nopts.n11.l {left} .os.nopts.n11.e {left frame w}
+
+ frame .os.nopts.n12
+ label .os.nopts.n12.l -text "taglength:" -width $lwidth -anchor w
+ entry .os.nopts.n12.e -width $ewidth -textvariable tko_taglength \
+ -relief raised
+ trace variable tko_taglength w tk_opt_ew
+ pack append .os.nopts.n12 \
+ .os.nopts.n12.l {left} .os.nopts.n12.e {left frame w}
+
+ frame .os.nopts.n13
+ label .os.nopts.n13.l -text "window:" -width $lwidth -anchor w
+ entry .os.nopts.n13.e -width $ewidth -textvariable tko_window \
+ -relief raised
+ trace variable tko_window w tk_opt_ew
+ pack append .os.nopts.n13 \
+ .os.nopts.n13.l {left} .os.nopts.n13.e {left frame w}
+
+ frame .os.nopts.n14
+ label .os.nopts.n14.l -text "wraplen:" -width $lwidth -anchor w
+ entry .os.nopts.n14.e -width $ewidth -textvariable tko_wraplen \
+ -relief raised
+ trace variable tko_wraplen w tk_opt_ew
+ pack append .os.nopts.n14 \
+ .os.nopts.n14.l {left} .os.nopts.n14.e {left frame w}
+
+ frame .os.nopts.n15
+ label .os.nopts.n15.l -text "wrapmargin:" -width $lwidth -anchor w
+ entry .os.nopts.n15.e -width $ewidth -textvariable tko_wrapmargin \
+ -relief raised
+ trace variable tko_wrapmargin w tk_opt_ew
+ pack append .os.nopts.n15 \
+ .os.nopts.n15.l {left} .os.nopts.n15.e {left frame w}
+
+ pack append .os.nopts \
+ .os.nopts.n1 {top fillx} \
+ .os.nopts.n3 {top expand fillx} \
+ .os.nopts.n4 {top expand fillx} \
+ .os.nopts.n5 {top expand fillx} \
+ .os.nopts.n6 {top expand fillx} \
+ .os.nopts.n7 {top expand fillx} \
+ .os.nopts.n8 {top expand fillx} \
+ .os.nopts.n9 {top expand fillx} \
+ .os.nopts.n10 {top expand fillx} \
+ .os.nopts.n11 {top expand fillx} \
+ .os.nopts.n12 {top expand fillx} \
+ .os.nopts.n13 {top expand fillx} \
+ .os.nopts.n14 {top expand fillx} \
+ .os.nopts.n15 {top expand fillx}
+
+ # Build frame for string options
+ frame .os.sopts
+
+ # Entry width.
+ set ewidth 40
+
+ frame .os.sopts.s1
+ label .os.sopts.s1.l -text "backup:" -width $lwidth -anchor w
+ entry .os.sopts.s1.e -width $ewidth -textvariable tko_backup \
+ -relief raised
+ pack append .os.sopts.s1 \
+ .os.sopts.s1.l {left} .os.sopts.s1.e {left frame w}
+
+ frame .os.sopts.s2
+ label .os.sopts.s2.l -text "cdpath:" -width $lwidth -anchor w
+ entry .os.sopts.s2.e -width $ewidth -textvariable tko_cdpath \
+ -relief raised
+ pack append .os.sopts.s2 \
+ .os.sopts.s2.l {left} .os.sopts.s2.e {left frame w}
+
+ frame .os.sopts.s3
+ label .os.sopts.s3.l -text "directory:" -width $lwidth -anchor w
+ entry .os.sopts.s3.e -width $ewidth -textvariable tko_directory \
+ -relief raised
+ pack append .os.sopts.s3 \
+ .os.sopts.s3.l {left} .os.sopts.s3.e {left frame w}
+
+ frame .os.sopts.s4
+ label .os.sopts.s4.l -text "cedit:" -width $lwidth -anchor w
+ entry .os.sopts.s4.e -width $ewidth -textvariable tko_cedit \
+ -relief raised
+ pack append .os.sopts.s4 \
+ .os.sopts.s4.l {left} .os.sopts.s4.e {left frame w}
+
+ frame .os.sopts.s5
+ label .os.sopts.s5.l -text "filec:" -width $lwidth -anchor w
+ entry .os.sopts.s5.e -width $ewidth -textvariable tko_filec \
+ -relief raised
+ pack append .os.sopts.s5 \
+ .os.sopts.s5.l {left} .os.sopts.s5.e {left frame w}
+
+ frame .os.sopts.s6
+ label .os.sopts.s6.l -text "msgcat:" -width $lwidth -anchor w
+ entry .os.sopts.s6.e -width $ewidth -textvariable tko_msgcat \
+ -relief raised
+ pack append .os.sopts.s6 \
+ .os.sopts.s6.l {left} .os.sopts.s6.e {left frame w}
+
+ frame .os.sopts.s7
+ label .os.sopts.s7.l -text "noprint:" -width $lwidth -anchor w
+ entry .os.sopts.s7.e -width $ewidth -textvariable tko_noprint \
+ -relief raised
+ pack append .os.sopts.s7 \
+ .os.sopts.s7.l {left} .os.sopts.s7.e {left frame w}
+
+ frame .os.sopts.s8
+ label .os.sopts.s8.l -text "paragraphs:" -width $lwidth -anchor w
+ entry .os.sopts.s8.e -width $ewidth -textvariable tko_paragraphs \
+ -relief raised
+ pack append .os.sopts.s8 \
+ .os.sopts.s8.l {left} .os.sopts.s8.e {left frame w}
+
+ frame .os.sopts.s9
+ label .os.sopts.s9.l -text "print:" -width $lwidth -anchor w
+ entry .os.sopts.s9.e -width $ewidth -textvariable tko_print \
+ -relief raised
+ pack append .os.sopts.s9 \
+ .os.sopts.s9.l {left} .os.sopts.s9.e {left frame w}
+
+ frame .os.sopts.s10
+ label .os.sopts.s10.l -text "recdir:" -width $lwidth -anchor w
+ entry .os.sopts.s10.e -width $ewidth -textvariable tko_recdir \
+ -relief raised
+ pack append .os.sopts.s10 \
+ .os.sopts.s10.l {left} .os.sopts.s10.e {left frame w}
+
+ frame .os.sopts.s11
+ label .os.sopts.s11.l -text "sections:" -width $lwidth -anchor w
+ entry .os.sopts.s11.e -width $ewidth -textvariable tko_sections \
+ -relief raised
+ pack append .os.sopts.s11 \
+ .os.sopts.s11.l {left} .os.sopts.s11.e {left frame w}
+
+ frame .os.sopts.s12
+ label .os.sopts.s12.l -text "shell:" -width $lwidth -anchor w
+ entry .os.sopts.s12.e -width $ewidth -textvariable tko_shell \
+ -relief raised
+ pack append .os.sopts.s12 \
+ .os.sopts.s12.l {left} .os.sopts.s12.e {left frame w}
+
+ frame .os.sopts.s13
+ label .os.sopts.s13.l -text "shellmeta:" -width $lwidth -anchor w
+ entry .os.sopts.s13.e -width $ewidth -textvariable tko_shellmeta \
+ -relief raised
+ pack append .os.sopts.s13 \
+ .os.sopts.s13.l {left} .os.sopts.s13.e {left frame w}
+
+ frame .os.sopts.s14
+ label .os.sopts.s14.l -text "tags:" -width $lwidth -anchor w
+ entry .os.sopts.s14.e -width $ewidth -textvariable tko_tags \
+ -relief raised
+ pack append .os.sopts.s14 \
+ .os.sopts.s14.l {left} .os.sopts.s14.e {left frame w}
+
+ frame .os.sopts.s15
+ label .os.sopts.s15.l -text "term:" -width $lwidth -anchor w
+ entry .os.sopts.s15.e -width $ewidth -textvariable tko_term \
+ -relief raised
+ pack append .os.sopts.s15 \
+ .os.sopts.s15.l {left} .os.sopts.s15.e {left frame w}
+
+ pack append .os.sopts \
+ .os.sopts.s1 {top expand fillx} \
+ .os.sopts.s2 {top expand fillx} \
+ .os.sopts.s3 {top expand fillx} \
+ .os.sopts.s4 {top expand fillx} \
+ .os.sopts.s5 {top expand fillx} \
+ .os.sopts.s6 {top expand fillx} \
+ .os.sopts.s7 {top expand fillx} \
+ .os.sopts.s8 {top expand fillx} \
+ .os.sopts.s9 {top expand fillx} \
+ .os.sopts.s10 {top expand fillx} \
+ .os.sopts.s11 {top expand fillx} \
+ .os.sopts.s12 {top expand fillx} \
+ .os.sopts.s13 {top expand fillx} \
+ .os.sopts.s14 {top expand fillx} \
+ .os.sopts.s15 {top expand fillx}
+
+ # Build frame for continue button.
+ frame .os.control -bd 4
+ button .os.control.quit -text "Continue" -command "destroy .os"
+ bind .os <Return> ".os.control.quit flash; destroy .os"
+ pack append .os.control .os.control.quit {left}
+
+ # Pack everything together.
+ pack append .os \
+ .os.bopts {top} \
+ .os.control {bottom fillx} \
+ .os.nopts {left fillx padx 4m pady 4m} \
+ .os.sopts {left fillx pady 4m}
+
+ grab .os
+ focus .os
+}
+
+# tk_opt_ew --
+# Handle a change to an option entry widget.
+proc tk_opt_ew {name element op} {
+ upvar $name x
+ tk_opt_set "$name=$x"
+}
+
+# tk_err --
+# Display a Tcl/Tk error message.
+proc tk_err {msg} {
+ tk_dialog .d {} "$msg" {} 0 Continue
+
+ #puts "msg: $msg"
+}
+
+# tk_addstr --
+# Add a string to the screen.
+proc tk_addstr {len str} {
+ global tk_cursor_row
+ global tk_cursor_col
+
+ # Delete the current characters, then insert the new ones.
+ .t mark set insert $tk_cursor_row.$tk_cursor_col
+ .t delete insert "insert + $len chars"
+ .t insert insert "$str"
+ incr tk_cursor_col $len
+
+ #puts "tk_addstr: row $tk_cursor_row col $tk_cursor_col: insert $str"
+}
+
+# tk_clrtoeol --
+# Clear to the end of the line.
+proc tk_clrtoeol {} {
+ global tk_cursor_row
+ global tk_cursor_col
+ global tk_ssize_col
+
+ # Overwrite to the end of the line with spaces.
+ .t mark set insert $tk_cursor_row.$tk_cursor_col
+ .t delete insert "insert lineend"
+ for {set j $tk_cursor_col} {$j < $tk_ssize_col} {incr j} {
+ .t insert insert " "
+ }
+
+ #puts "tk_clrtoel: row $tk_cursor_row col $tk_cursor_col"
+}
+
+# tk_deleteln --
+# Delete the line.
+proc tk_deleteln {} {
+ global tk_cursor_row
+ global tk_cursor_col
+ global tk_ssize_col
+
+ # Delete the line.
+ .t mark set insert $tk_cursor_row.$tk_cursor_col
+ .t delete insert "insert lineend + 1 chars"
+
+ # Append a new, blank line at the end of the screen.
+ .t mark set insert end
+ for {set j 1} {$j <= $tk_ssize_col} {incr j} {
+ .t insert insert " "
+ }
+ .t insert insert "\n"
+
+ #puts "tk_deleteln: row $tk_cursor_row"
+}
+
+# tk_flash --
+# Flash the screen.
+proc tk_flash {} {
+ set bg [lindex [.t config -background] 4]
+ set fg [lindex [.t config -foreground] 4]
+ .t configure -background $fg -foreground $bg
+ update idletasks
+ .t configure -background $bg -foreground $fg
+ update idletasks
+}
+
+# tk_insertln --
+# Insert the line.
+proc tk_insertln {} {
+ global tk_cursor_row
+ global tk_cursor_col
+ global tk_ssize_row
+ global tk_ssize_col
+
+ # Delete the last line on the screen.
+ .t mark set insert $tk_ssize_row.0
+ .t delete insert "insert lineend + 1 chars"
+
+ # Insert a new, blank line.
+ .t mark set insert $tk_cursor_row.$tk_cursor_col
+ for {set j 1} {$j <= $tk_ssize_col} {incr j} {
+ .t insert insert " "
+ }
+ .t insert insert "\n"
+
+ #puts "tk_insertln: row $tk_cursor_row"
+}
+
+# tk_move --
+# Move the cursor.
+proc tk_move {row col} {
+ global tk_cursor_row
+ global tk_cursor_col
+
+ # Convert to Tcl/Tk coordinates, update the insert cursor.
+ set tk_cursor_row [ expr $row + 1 ]
+ set tk_cursor_col $col
+ .t mark set insert $tk_cursor_row.$tk_cursor_col
+
+ # Update the screen cursor.
+ .t tag remove tk_cursor tk_cursor_indx
+ .t mark set tk_cursor_indx insert
+ .t tag add tk_cursor tk_cursor_indx
+
+ #puts "tk_move: row $tk_cursor_row col $tk_cursor_col"
+}
+
+# tk_rename --
+# Rename the screen.
+proc tk_rename {name} {
+ wm title . "$name"
+}
+
+# tk_ssize --
+# Return the window size.
+proc tk_ssize {} {
+ global tk_ssize_col
+ global tk_ssize_row
+
+ set s [ .t configure -width ]
+ set tk_ssize_col [ lindex $s [ expr [ llength $s ] -1 ] ]
+ set s [ .t configure -height ]
+ set tk_ssize_row [ lindex $s [ expr [ llength $s ] -1 ] ]
+
+ #puts "tk_ssize: rows $tk_ssize_row, cols $tk_ssize_col"
+}
+
+# tk_standout --
+# Change into standout mode.
+proc tk_standout {} {
+}
+
+# tk_standend --
+# Change out of standout mode.
+proc tk_standend {} {
+}
+
+# Cursor
+set tk_cursor_row 1
+set tk_cursor_col 0
+
+# Screen size
+set tk_ssize_row 0
+set tk_ssize_col 0
+
+screen
+#tkwait window .
diff --git a/contrib/nvi/tk/tk_funcs.c b/contrib/nvi/tk/tk_funcs.c
new file mode 100644
index 0000000..be2b0d9
--- /dev/null
+++ b/contrib/nvi/tk/tk_funcs.c
@@ -0,0 +1,346 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_funcs.c 8.11 (Berkeley) 9/23/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/time.h>
+
+#include <bitstring.h>
+#include <ctype.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "../vi/vi.h"
+#include "tki.h"
+
+/*
+ * tk_addstr --
+ * Add len bytes from the string at the cursor, advancing the cursor.
+ *
+ * PUBLIC: int tk_addstr __P((SCR *, const char *, size_t));
+ */
+int
+tk_addstr(sp, str, len)
+ SCR *sp;
+ const char *str;
+ size_t len;
+{
+ TK_PRIVATE *tkp;
+ int iv;
+ char buf[20];
+
+ iv = 0;
+
+ tkp = TKP(sp);
+ if (iv)
+ (void)Tcl_Eval(tkp->interp, "tk_standout");
+
+ (void)snprintf(buf, sizeof(buf), "%d ", (int)len);
+ if ((Tcl_VarEval(tkp->interp,
+ "tk_addstr ", buf, "{", str, "}", NULL) != TCL_OK))
+ return (1);
+
+ if (iv)
+ (void)Tcl_Eval(tkp->interp, "tk_standend");
+ return (0);
+}
+
+/*
+ * tk_attr --
+ * Toggle a screen attribute on/off.
+ *
+ * PUBLIC: int tk_attr __P((SCR *, scr_attr_t, int));
+ */
+int
+tk_attr(sp, attribute, on)
+ SCR *sp;
+ scr_attr_t attribute;
+ int on;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ switch (attribute) {
+ case SA_ALTERNATE: /* No alternate screen. */
+ break;
+ case SA_INVERSE:
+ if (on)
+ (void)Tcl_Eval(tkp->interp, "tk_standout");
+ else
+ (void)Tcl_Eval(tkp->interp, "tk_standend");
+ break;
+ default:
+ abort();
+ }
+ return (0);
+}
+
+/*
+ * tk_baud --
+ * Return the baud rate.
+ *
+ * PUBLIC: int tk_baud __P((SCR *, u_long *));
+ */
+int
+tk_baud(sp, ratep)
+ SCR *sp;
+ u_long *ratep;
+{
+ *ratep = 9600;
+ return (0);
+}
+
+/*
+ * tk_bell --
+ * Ring the bell/flash the screen.
+ *
+ * PUBLIC: int tk_bell __P((SCR *));
+ */
+int
+tk_bell(sp)
+ SCR *sp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ return (Tcl_Eval(tkp->interp, "tk_flash") != TCL_OK);
+}
+
+/*
+ * tk_clrtoeol --
+ * Clear from the current cursor to the end of the line.
+ *
+ * PUBLIC: int tk_clrtoeol __P((SCR *));
+ */
+int
+tk_clrtoeol(sp)
+ SCR *sp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ return (Tcl_Eval(tkp->interp, "tk_clrtoeol") != TCL_OK);
+}
+
+/*
+ * tk_cursor --
+ * Return the current cursor position.
+ *
+ * PUBLIC: int tk_cursor __P((SCR *, size_t *, size_t *));
+ */
+int
+tk_cursor(sp, yp, xp)
+ SCR *sp;
+ size_t *yp, *xp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ *yp = (tkp->tk_cursor_row - 1) - sp->woff;
+ *xp = tkp->tk_cursor_col;
+ return (0);
+}
+
+/*
+ * tk_deleteln --
+ * Delete the current line, scrolling all lines below it.
+ *
+ * PUBLIC: int tk_deleteln __P((SCR *));
+ */
+int
+tk_deleteln(sp)
+ SCR *sp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ return (Tcl_Eval(tkp->interp, "tk_deleteln") != TCL_OK);
+}
+
+/*
+ * tk_ex_adjust --
+ * Adjust the screen for ex.
+ *
+ * PUBLIC: int tk_ex_adjust __P((SCR *, exadj_t));
+ */
+int
+tk_ex_adjust(sp, action)
+ SCR *sp;
+ exadj_t action;
+{
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * tk_insertln --
+ * Push down the current line, discarding the bottom line.
+ *
+ * PUBLIC: int tk_insertln __P((SCR *));
+ */
+int
+tk_insertln(sp)
+ SCR *sp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ return (Tcl_Eval(tkp->interp, "tk_insertln") != TCL_OK);
+}
+
+/*
+ * tk_keyval --
+ * Return the value for a special key.
+ *
+ * PUBLIC: int tk_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
+ */
+int
+tk_keyval(sp, val, chp, dnep)
+ SCR *sp;
+ scr_keyval_t val;
+ CHAR_T *chp;
+ int *dnep;
+{
+ TK_PRIVATE *tkp;
+
+ /*
+ * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
+ * VWERASE is a 4BSD extension.
+ */
+ tkp = TKP(sp);
+ switch (val) {
+ case KEY_VEOF:
+ *dnep = (*chp = tkp->orig.c_cc[VEOF]) == _POSIX_VDISABLE;
+ break;
+ case KEY_VERASE:
+ *dnep = (*chp = tkp->orig.c_cc[VERASE]) == _POSIX_VDISABLE;
+ break;
+ case KEY_VKILL:
+ *dnep = (*chp = tkp->orig.c_cc[VKILL]) == _POSIX_VDISABLE;
+ break;
+#ifdef VWERASE
+ case KEY_VWERASE:
+ *dnep = (*chp = tkp->orig.c_cc[VWERASE]) == _POSIX_VDISABLE;
+ break;
+#endif
+ default:
+ *dnep = 1;
+ break;
+ }
+ return (0);
+}
+
+/*
+ * tk_move --
+ * Move the cursor.
+ *
+ * PUBLIC: int tk_move __P((SCR *, size_t, size_t));
+ */
+int
+tk_move(sp, lno, cno)
+ SCR *sp;
+ size_t lno, cno;
+{
+ TK_PRIVATE *tkp;
+ char buf[40];
+
+ (void)snprintf(buf, sizeof(buf), "%d %d", RLNO(sp, lno), cno);
+
+ tkp = TKP(sp);
+ return (Tcl_VarEval(tkp->interp, "tk_move ", buf, NULL) != TCL_OK);
+}
+
+/*
+ * tk_refresh --
+ * Refresh the screen.
+ *
+ * PUBLIC: int tk_refresh __P((SCR *, int));
+ */
+int
+tk_refresh(sp, repaint)
+ SCR *sp;
+ int repaint;
+{
+ TK_PRIVATE *tkp;
+
+ /*
+ * If repaint is set, the editor is telling us that we don't know
+ * what's on the screen, so we have to repaint from scratch.
+ *
+ * XXX
+ * I have no idea how to do this in Tk. My guess is that we have
+ * to delete all of the text and call the editor with an E_REPAINT
+ * event.
+ */
+ if (repaint) {
+ }
+
+ tkp = TKP(sp);
+ return (Tcl_Eval(tkp->interp, "update idletasks") != TCL_OK);
+}
+
+/*
+ * tk_rename --
+ * Rename the file.
+ *
+ * PUBLIC: int tk_rename __P((SCR *));
+ */
+int
+tk_rename(sp)
+ SCR *sp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+ return (Tcl_VarEval(tkp->interp,
+ "tk_rename ", sp->frp->name, NULL) != TCL_OK);
+}
+
+/*
+ * tk_suspend --
+ * Suspend a screen.
+ *
+ * PUBLIC: int tk_suspend __P((SCR *, int *));
+ */
+int
+tk_suspend(sp, allowedp)
+ SCR *sp;
+ int *allowedp;
+{
+ *allowedp = 0;
+ return (0);
+}
+
+/*
+ * tk_usage --
+ * Print out the Tk/Tcl usage messages.
+ *
+ * PUBLIC: void tk_usage __P((void));
+ */
+void
+tk_usage()
+{
+#define USAGE "\
+usage: tkvi [-eFlRrSv] [-c command] [-bg color] [-fg color]\n\
+ [-geometry widthxheight+x+y] [-i script] [-t tag] [-w size]\n\
+ [file ...]\n"
+ (void)fprintf(stderr, "%s", USAGE);
+#undef USAGE
+}
diff --git a/contrib/nvi/tk/tk_main.c b/contrib/nvi/tk/tk_main.c
new file mode 100644
index 0000000..c2f34e7
--- /dev/null
+++ b/contrib/nvi/tk/tk_main.c
@@ -0,0 +1,423 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_main.c 8.18 (Berkeley) 9/24/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "tki.h"
+#include "pathnames.h"
+
+GS *__global_list; /* GLOBAL: List of screens. */
+sigset_t __sigblockset; /* GLOBAL: Blocked signals. */
+
+static GS *gs_init __P((char *));
+static void killsig __P((SCR *));
+static void perr __P((char *, char *));
+static void sig_end __P((GS *));
+static int sig_init __P((GS *));
+static int tcl_init __P((GS *));
+static void tcl_err __P((TK_PRIVATE *));
+
+/*
+ * main --
+ * This is the main loop for the standalone Tcl/Tk editor.
+ */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ static int reenter;
+ GS *gp;
+ TK_PRIVATE *tkp;
+ size_t rows, cols;
+ int rval;
+ char **p_av, **t_av, *script;
+
+ /* If loaded at 0 and jumping through a NULL pointer, stop. */
+ if (reenter++)
+ abort();
+
+ /* Create and initialize the global structure. */
+ __global_list = gp = gs_init(argv[0]);
+
+ /* Initialize Tk/Tcl. */
+ if (tcl_init(gp))
+ exit (1);
+
+ /*
+ * Strip out any arguments that the common editor doesn't understand
+ * (i.e. the Tk/Tcl arguments). Search for -i first, it's the Tk/Tcl
+ * startup script and needs to be run first.
+ *
+ * XXX
+ * There's no way to portably call getopt twice.
+ */
+ script = "init.tcl";
+ for (p_av = t_av = argv;;) {
+ if (*t_av == NULL) {
+ *p_av = NULL;
+ break;
+ }
+ if (!strcmp(*t_av, "--")) {
+ while ((*p_av++ = *t_av++) != NULL);
+ break;
+ }
+ if (!memcmp(*t_av, "-i", sizeof("-i") - 1)) {
+ if (t_av[0][2] != '\0') {
+ script = t_av[0] + 2;
+ ++t_av;
+ --argc;
+ continue;
+ }
+ if (t_av[1] != NULL) {
+ script = t_av[1];
+ t_av += 2;
+ argc -= 2;
+ continue;
+ }
+ }
+ *p_av++ = *t_av++;
+ }
+ for (p_av = t_av = argv;;) {
+ if (*t_av == NULL) {
+ *p_av = NULL;
+ break;
+ }
+ if (!strcmp(*t_av, "--")) {
+ while ((*p_av++ = *t_av++) != NULL);
+ break;
+ }
+ if (t_av[1] != NULL &&
+ (!memcmp(*t_av, "-background", sizeof("-background") - 1) ||
+ !memcmp(*t_av, "-bg", sizeof("-bg") - 1) ||
+ !memcmp(*t_av, "-borderwidth", sizeof("-borderwidth") - 1)||
+ !memcmp(*t_av, "-bd", sizeof("-bd") - 1) ||
+ !memcmp(*t_av, "-foreground", sizeof("-foreground") - 1) ||
+ !memcmp(*t_av, "-fg", sizeof("-fg") - 1) ||
+ !memcmp(*t_av, "-font", sizeof("-font") - 1))) {
+ if (Tcl_VarEval(tkp->interp, ".t configure ",
+ t_av[0], " ", t_av[1], NULL) == TCL_ERROR)
+ tcl_err(tkp);
+ t_av += 2;
+ argc -= 2;
+ continue;
+ }
+ if (!memcmp(*t_av, "-geometry", sizeof("-geometry") - 1)) {
+ if (Tcl_VarEval(tkp->interp, "wm geometry . ",
+ *t_av + sizeof("-geometry") - 1, NULL) == TCL_ERROR)
+ tcl_err(tkp);
+ ++t_av;
+ --argc;
+ continue;
+ }
+ *p_av++ = *t_av++;
+ }
+
+ /* Load the initial Tcl/Tk script. */
+ tkp = GTKP(gp);
+ if (Tcl_EvalFile(tkp->interp, script) == TCL_ERROR)
+ tcl_err(tkp);
+
+ /* Add the terminal type to the global structure. */
+ if ((OG_D_STR(gp, GO_TERM) =
+ OG_STR(gp, GO_TERM) = strdup("tkterm")) == NULL)
+ perr(gp->progname, NULL);
+
+ /* Figure out how big the screen is. */
+ if (tk_ssize(NULL, 0, &rows, &cols, NULL))
+ exit (1);
+
+ /* Add the rows and columns to the global structure. */
+ OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows;
+ OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols;
+
+ /* Start catching signals. */
+ if (sig_init(gp))
+ exit (1);
+
+ /* Run ex/vi. */
+ rval = editor(gp, argc, argv);
+
+ /* Clean up signals. */
+ sig_end(gp);
+
+ /* Clean up the terminal. */
+ (void)tk_quit(gp);
+
+ /* If a killer signal arrived, pretend we just got it. */
+ if (tkp->killersig) {
+ (void)signal(tkp->killersig, SIG_DFL);
+ (void)kill(getpid(), tkp->killersig);
+ /* NOTREACHED */
+ }
+
+ /* Free the global and TK private areas. */
+#if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
+ free(tkp);
+ free(gp);
+#endif
+
+ exit (rval);
+}
+
+/*
+ * gs_init --
+ * Create and partially initialize the GS structure.
+ */
+static GS *
+gs_init(name)
+ char *name;
+{
+ TK_PRIVATE *tkp;
+ GS *gp;
+ int fd;
+ char *p;
+
+ /* Figure out what our name is. */
+ if ((p = strrchr(name, '/')) != NULL)
+ name = p + 1;
+
+ /* Allocate the global structure. */
+ CALLOC_NOMSG(NULL, gp, GS *, 1, sizeof(GS));
+
+ /* Allocate the CL private structure. */
+ if (gp != NULL)
+ CALLOC_NOMSG(NULL, tkp, TK_PRIVATE *, 1, sizeof(TK_PRIVATE));
+ if (gp == NULL || tkp == NULL)
+ perr(name, NULL);
+ gp->tk_private = tkp;
+ TAILQ_INIT(&tkp->evq);
+
+ /* Initialize the list of curses functions. */
+ gp->scr_addstr = tk_addstr;
+ gp->scr_attr = tk_attr;
+ gp->scr_baud = tk_baud;
+ gp->scr_bell = tk_bell;
+ gp->scr_busy = NULL;
+ gp->scr_clrtoeol = tk_clrtoeol;
+ gp->scr_cursor = tk_cursor;
+ gp->scr_deleteln = tk_deleteln;
+ gp->scr_event = tk_event;
+ gp->scr_ex_adjust = tk_ex_adjust;
+ gp->scr_fmap = tk_fmap;
+ gp->scr_insertln = tk_insertln;
+ gp->scr_keyval = tk_keyval;
+ gp->scr_move = tk_move;
+ gp->scr_msg = NULL;
+ gp->scr_optchange = tk_optchange;
+ gp->scr_refresh = tk_refresh;
+ gp->scr_rename = tk_rename;
+ gp->scr_screen = tk_screen;
+ gp->scr_suspend = tk_suspend;
+ gp->scr_usage = tk_usage;
+
+ /*
+ * We expect that if we've lost our controlling terminal that the
+ * open() (but not the tcgetattr()) will fail.
+ */
+ if (isatty(STDIN_FILENO)) {
+ if (tcgetattr(STDIN_FILENO, &tkp->orig) == -1)
+ goto tcfail;
+ } else if ((fd = open(_PATH_TTY, O_RDONLY, 0)) != -1) {
+ if (tcgetattr(fd, &tkp->orig) == -1)
+tcfail: perr(name, "tcgetattr");
+ (void)close(fd);
+ }
+
+ gp->progname = name;
+ return (gp);
+}
+
+/*
+ * tcl_init --
+ * Get Tcl/Tk up and running.
+ */
+static int
+tcl_init(gp)
+ GS *gp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = GTKP(gp);
+ if ((tkp->interp = Tcl_CreateInterp()) == NULL)
+ tcl_err(tkp);
+ /* XXX: Tk 4.1 has an incompatible change. */
+#if (TK_MAJOR_VERSION == 4) && (TK_MINOR_VERSION == 0)
+ if (Tk_CreateMainWindow(tkp->interp, NULL, "vi", "Vi") == NULL)
+ tcl_err(tkp);
+#endif
+ if (Tcl_Init(tkp->interp) == TCL_ERROR)
+ tcl_err(tkp);
+ if (Tk_Init(tkp->interp) == TCL_ERROR)
+ tcl_err(tkp);
+
+ /* Shared variables. */
+ (void)Tcl_LinkVar(tkp->interp,
+ "tk_cursor_row", (char *)&tkp->tk_cursor_row, TCL_LINK_INT);
+ (void)Tcl_LinkVar(tkp->interp,
+ "tk_cursor_col", (char *)&tkp->tk_cursor_col, TCL_LINK_INT);
+ (void)Tcl_LinkVar(tkp->interp,
+ "tk_ssize_row", (char *)&tkp->tk_ssize_row, TCL_LINK_INT);
+ (void)Tcl_LinkVar(tkp->interp,
+ "tk_ssize_col", (char *)&tkp->tk_ssize_col, TCL_LINK_INT);
+
+ /* Functions called by Tcl script. */
+ Tcl_CreateCommand(tkp->interp, "tk_key", tk_key, tkp, NULL);
+ Tcl_CreateCommand(tkp->interp, "tk_op", tk_op, tkp, NULL);
+ Tcl_CreateCommand(tkp->interp, "tk_opt_init", tk_opt_init, tkp, NULL);
+ Tcl_CreateCommand(tkp->interp, "tk_opt_set", tk_opt_set, tkp, NULL);
+ Tcl_CreateCommand(tkp->interp, "tk_version", tk_version, tkp, NULL);
+
+ /* Other initialization. */
+ if (Tcl_Eval(tkp->interp, "wm geometry . =80x28+0+0") == TCL_ERROR)
+ tcl_err(tkp);
+ return (0);
+}
+
+/*
+ * tcl_err --
+ * Tcl/Tk error message during initialization.
+ */
+static void
+tcl_err(tkp)
+ TK_PRIVATE *tkp;
+{
+ (void)fprintf(stderr, "%s\n", tkp->interp->result != NULL ?
+ tkp->interp->result : "Tcl/Tk: initialization error");
+ (void)tk_usage();
+ exit (1);
+}
+
+#define GLOBAL_TKP \
+ TK_PRIVATE *tkp = GTKP(__global_list);
+static void
+h_hup(signo)
+ int signo;
+{
+ GLOBAL_TKP;
+
+ F_SET(tkp, TK_SIGHUP);
+ tkp->killersig = SIGHUP;
+}
+
+static void
+h_int(signo)
+ int signo;
+{
+ GLOBAL_TKP;
+
+ F_SET(tkp, TK_SIGINT);
+}
+
+static void
+h_term(signo)
+ int signo;
+{
+ GLOBAL_TKP;
+
+ F_SET(tkp, TK_SIGTERM);
+ tkp->killersig = SIGTERM;
+}
+
+static void
+h_winch(signo)
+ int signo;
+{
+ GLOBAL_TKP;
+
+ F_SET(tkp, TK_SIGWINCH);
+}
+#undef GLOBAL_TKP
+
+/*
+ * sig_init --
+ * Initialize signals.
+ */
+static int
+sig_init(gp)
+ GS *gp;
+{
+ TK_PRIVATE *tkp;
+ struct sigaction act;
+
+ tkp = GTKP(gp);
+
+ (void)sigemptyset(&__sigblockset);
+
+ /*
+ * Use sigaction(2), not signal(3), since we don't always want to
+ * restart system calls. The example is when waiting for a command
+ * mode keystroke and SIGWINCH arrives. Besides, you can't portably
+ * restart system calls (thanks, POSIX!).
+ */
+#define SETSIG(signal, handler, off) { \
+ if (sigaddset(&__sigblockset, signal)) \
+ goto err; \
+ act.sa_handler = handler; \
+ sigemptyset(&act.sa_mask); \
+ act.sa_flags = 0; \
+ if (sigaction(signal, &act, &tkp->oact[off])) \
+ goto err; \
+}
+#undef SETSIG
+ return (0);
+
+err: perr(gp->progname, NULL);
+ return (1);
+}
+
+/*
+ * sig_end --
+ * End signal setup.
+ */
+static void
+sig_end(gp)
+ GS *gp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = GTKP(gp);
+ (void)sigaction(SIGHUP, NULL, &tkp->oact[INDX_HUP]);
+ (void)sigaction(SIGINT, NULL, &tkp->oact[INDX_INT]);
+ (void)sigaction(SIGTERM, NULL, &tkp->oact[INDX_TERM]);
+ (void)sigaction(SIGWINCH, NULL, &tkp->oact[INDX_WINCH]);
+}
+
+/*
+ * perr --
+ * Print system error.
+ */
+static void
+perr(name, msg)
+ char *name, *msg;
+{
+ (void)fprintf(stderr, "%s:", name);
+ if (msg != NULL)
+ (void)fprintf(stderr, "%s:", msg);
+ (void)fprintf(stderr, "%s\n", strerror(errno));
+ exit(1);
+}
diff --git a/contrib/nvi/tk/tk_read.c b/contrib/nvi/tk/tk_read.c
new file mode 100644
index 0000000..b5cfab7
--- /dev/null
+++ b/contrib/nvi/tk/tk_read.c
@@ -0,0 +1,207 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_read.c 8.12 (Berkeley) 9/24/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "../ex/script.h"
+#include "tki.h"
+
+static input_t tk_read __P((SCR *, int));
+static int tk_resize __P((SCR *, size_t, size_t));
+
+
+/*
+ * tk_event --
+ * Return a single event.
+ *
+ * PUBLIC: int tk_event __P((SCR *, EVENT *, u_int32_t, int));
+ */
+int
+tk_event(sp, evp, flags, timeout)
+ SCR *sp;
+ EVENT *evp;
+ u_int32_t flags;
+ int timeout;
+{
+ EVENT *tevp;
+ TK_PRIVATE *tkp;
+ size_t lines, columns;
+ int changed;
+
+ /*
+ * Queue signal based events. We never clear SIGHUP or SIGTERM events,
+ * so that we just keep returning them until the editor dies.
+ */
+ tkp = TKP(sp);
+sig: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(tkp, TK_SIGINT)) {
+ if (F_ISSET(tkp, TK_SIGINT)) {
+ F_CLR(tkp, TK_SIGINT);
+ evp->e_event = E_INTERRUPT;
+ } else
+ evp->e_event = E_TIMEOUT;
+ return (0);
+ }
+ if (F_ISSET(tkp, TK_SIGHUP | TK_SIGTERM | TK_SIGWINCH)) {
+ if (F_ISSET(tkp, TK_SIGHUP)) {
+ evp->e_event = E_SIGHUP;
+ return (0);
+ }
+ if (F_ISSET(tkp, TK_SIGTERM)) {
+ evp->e_event = E_SIGTERM;
+ return (0);
+ }
+ if (F_ISSET(tkp, TK_SIGWINCH)) {
+ F_CLR(tkp, TK_SIGWINCH);
+ (void)tk_ssize(sp, 1, &lines, &columns, &changed);
+ if (changed) {
+ (void)tk_resize(sp, lines, columns);
+ evp->e_event = E_WRESIZE;
+ return (0);
+ }
+ /* No change, so ignore the signal. */
+ }
+ }
+
+ /* Queue special ops. */
+ops: if ((tevp = tkp->evq.tqh_first) != NULL) {
+ *evp = *tevp;
+ TAILQ_REMOVE(&tkp->evq, tevp, q);
+ free(tevp);
+ return (0);
+ }
+
+ /* Read input characters. */
+ switch (tk_read(sp, timeout)) {
+ case INP_OK:
+ evp->e_csp = tkp->ibuf;
+ evp->e_len = tkp->ibuf_cnt;
+ evp->e_event = E_STRING;
+ tkp->ibuf_cnt = 0;
+ break;
+ case INP_EOF:
+ evp->e_event = E_EOF;
+ break;
+ case INP_ERR:
+ evp->e_event = E_ERR;
+ break;
+ case INP_INTR:
+ goto sig;
+ break;
+ case INP_TIMEOUT:
+ /* May have returned because queued a special op. */
+ if (tkp->evq.tqh_first != NULL)
+ goto ops;
+
+ /* Otherwise, we timed out. */
+ evp->e_event = E_TIMEOUT;
+ break;
+ default:
+ abort();
+ }
+ return (0);
+}
+
+/*
+ * tk_read --
+ * Read characters from the input.
+ */
+static input_t
+tk_read(sp, timeout)
+ SCR *sp;
+ int timeout;
+{
+ TK_PRIVATE *tkp;
+ char buf[20];
+
+ /*
+ * Check scripting window file descriptors. It's ugly that we wait
+ * on scripting file descriptors here, but it's the only way to keep
+ * from locking out scripting windows.
+ */
+ if (F_ISSET(sp->gp, G_SCRWIN) && sscr_input(sp))
+ return (INP_ERR);
+
+ /* Read characters. */
+ tkp = TKP(sp);
+ (void)snprintf(buf, sizeof(buf), "%d", timeout);
+ (void)Tcl_VarEval(tkp->interp, "tk_key_wait ", buf, NULL);
+
+ return (tkp->ibuf_cnt == 0 ? INP_TIMEOUT : INP_OK);
+}
+
+/*
+ * tk_key --
+ * Receive an input key.
+ *
+ * PUBLIC: int tk_key __P((ClientData, Tcl_Interp *, int, char *[]));
+ */
+int
+tk_key(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ TK_PRIVATE *tkp;
+ u_int8_t *p, *t;
+
+ tkp = (TK_PRIVATE *)clientData;
+ for (p =
+ tkp->ibuf + tkp->ibuf_cnt, t = argv[1]; (*p++ = *t++) != '\0';
+ ++tkp->ibuf_cnt);
+ return (TCL_OK);
+}
+
+/*
+ * tk_resize --
+ * Reset the options for a resize event.
+ */
+static int
+tk_resize(sp, lines, columns)
+ SCR *sp;
+ size_t lines, columns;
+{
+ ARGS *argv[2], a, b;
+ int rval;
+ char b1[1024];
+
+ a.bp = b1;
+ b.bp = NULL;
+ a.len = b.len = 0;
+ argv[0] = &a;
+ argv[1] = &b;
+
+ (void)snprintf(b1, sizeof(b1), "lines=%lu", (u_long)lines);
+ a.len = strlen(b1);
+ if (opts_set(sp, argv, NULL))
+ return (1);
+ (void)snprintf(b1, sizeof(b1), "columns=%lu", (u_long)columns);
+ a.len = strlen(b1);
+ if (opts_set(sp, argv, NULL))
+ return (1);
+ return (0);
+}
diff --git a/contrib/nvi/tk/tk_screen.c b/contrib/nvi/tk/tk_screen.c
new file mode 100644
index 0000000..e109093
--- /dev/null
+++ b/contrib/nvi/tk/tk_screen.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_screen.c 8.9 (Berkeley) 5/24/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "tki.h"
+
+/*
+ * tk_screen --
+ * Initialize/shutdown the Tcl/Tk screen.
+ *
+ * PUBLIC: int tk_screen __P((SCR *, u_int32_t));
+ */
+int
+tk_screen(sp, flags)
+ SCR *sp;
+ u_int32_t flags;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = TKP(sp);
+
+ /* See if we're already in the right mode. */
+ if (LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI))
+ return (0);
+
+ /* Ex isn't possible. */
+ if (LF_ISSET(SC_EX))
+ return (1);
+
+ /* Initialize terminal based information. */
+ if (tk_term_init(sp))
+ return (1);
+
+ /* Put up the first file name. */
+ if (tk_rename(sp))
+ return (1);
+
+ F_SET(tkp, TK_SCR_VI_INIT);
+ return (0);
+}
+
+/*
+ * tk_quit --
+ * Shutdown the screens.
+ *
+ * PUBLIC: int tk_quit __P((GS *));
+ */
+int
+tk_quit(gp)
+ GS *gp;
+{
+ TK_PRIVATE *tkp;
+ int rval;
+
+ /* Clean up the terminal mappings. */
+ rval = tk_term_end(gp);
+
+ tkp = GTKP(gp);
+ F_CLR(tkp, TK_SCR_VI_INIT);
+
+ return (rval);
+}
diff --git a/contrib/nvi/tk/tk_term.c b/contrib/nvi/tk/tk_term.c
new file mode 100644
index 0000000..18299a2
--- /dev/null
+++ b/contrib/nvi/tk/tk_term.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_term.c 8.12 (Berkeley) 10/13/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "tki.h"
+
+/*
+ * tk_term_init --
+ * Initialize the terminal special keys.
+ *
+ * PUBLIC: int tk_term_init __P((SCR *));
+ */
+int
+tk_term_init(sp)
+ SCR *sp;
+{
+ SEQ *qp;
+
+ /*
+ * Rework any function key mappings that were set before the
+ * screen was initialized.
+ */
+ for (qp = sp->gp->seqq.lh_first; qp != NULL; qp = qp->q.le_next)
+ if (F_ISSET(qp, SEQ_FUNCMAP))
+ (void)tk_fmap(sp, qp->stype,
+ qp->input, qp->ilen, qp->output, qp->olen);
+ return (0);
+}
+
+/*
+ * tk_term_end --
+ * End the special keys defined by the termcap/terminfo entry.
+ *
+ * PUBLIC: int tk_term_end __P((GS *));
+ */
+int
+tk_term_end(gp)
+ GS *gp;
+{
+ SEQ *qp, *nqp;
+
+ /* Delete screen specific mappings. */
+ for (qp = gp->seqq.lh_first; qp != NULL; qp = nqp) {
+ nqp = qp->q.le_next;
+ if (F_ISSET(qp, SEQ_SCREEN))
+ (void)seq_mdel(qp);
+ }
+ return (0);
+}
+
+/*
+ * tk_fmap --
+ * Map a function key.
+ *
+ * PUBLIC: int tk_fmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t));
+ */
+int
+tk_fmap(sp, stype, from, flen, to, tlen)
+ SCR *sp;
+ seq_t stype;
+ CHAR_T *from, *to;
+ size_t flen, tlen;
+{
+ VI_INIT_IGNORE(sp);
+
+ /* Bind a Tk/Tcl function key to a string sequence. */
+ return (0);
+}
+
+/*
+ * tk_optchange --
+ * Curses screen specific "option changed" routine.
+ *
+ * PUBLIC: int tk_optchange __P((SCR *, int, char *, u_long *));
+ */
+int
+tk_optchange(sp, opt, str, valp)
+ SCR *sp;
+ int opt;
+ char *str;
+ u_long *valp;
+{
+ switch (opt) {
+ case O_COLUMNS:
+ case O_LINES:
+ /*
+ * Changing the columns or lines require that we restart
+ * the screen.
+ */
+ F_SET(sp->gp, G_SRESTART);
+ F_CLR(sp, SC_SCR_EX | SC_SCR_VI);
+ break;
+ case O_TERM:
+ msgq(sp, M_ERR, "The screen type may not be changed");
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * tk_ssize --
+ * Return the window size.
+ *
+ * PUBLIC: int tk_ssize __P((SCR *, int, size_t *, size_t *, int *));
+ */
+int
+tk_ssize(sp, sigwinch, rowp, colp, changedp)
+ SCR *sp;
+ int sigwinch;
+ size_t *rowp, *colp;
+ int *changedp;
+{
+ TK_PRIVATE *tkp;
+
+ tkp = GTKP(__global_list);
+ (void)Tcl_Eval(tkp->interp, "tk_ssize");
+
+ /*
+ * SunOS systems deliver SIGWINCH when windows are uncovered
+ * as well as when they change size. In addition, we call
+ * here when continuing after being suspended since the window
+ * may have changed size. Since we don't want to background
+ * all of the screens just because the window was uncovered,
+ * ignore the signal if there's no change.
+ *
+ * !!!
+ * sp may be NULL.
+ */
+ if (sigwinch && sp != NULL &&
+ tkp->tk_ssize_row == O_VAL(sp, O_LINES) &&
+ tkp->tk_ssize_col == O_VAL(sp, O_COLUMNS)) {
+ if (changedp != NULL)
+ *changedp = 0;
+ return (0);
+ }
+
+ if (rowp != NULL)
+ *rowp = tkp->tk_ssize_row;
+ if (colp != NULL)
+ *colp = tkp->tk_ssize_col;
+ if (changedp != NULL)
+ *changedp = 1;
+ return (0);
+}
diff --git a/contrib/nvi/tk/tk_util.c b/contrib/nvi/tk/tk_util.c
new file mode 100644
index 0000000..096fa7b
--- /dev/null
+++ b/contrib/nvi/tk/tk_util.c
@@ -0,0 +1,250 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)tk_util.c 8.14 (Berkeley) 7/19/96";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <bitstring.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "../common/common.h"
+#include "tki.h"
+
+static int tk_op_push __P((SCR *, TK_PRIVATE *, e_event_t));
+
+/*
+ * tk_op --
+ * Events provided directly from Tcl/Tk.
+ *
+ * PUBLIC: int tk_op __P((ClientData, Tcl_Interp *, int, char *[]));
+ */
+int
+tk_op(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ SCR *sp;
+ TK_PRIVATE *tkp;
+
+ sp = __global_list->dq.cqh_first; /* XXX */
+ tkp = (TK_PRIVATE *)clientData;
+
+ switch (argv[1][0]) {
+ case 'q':
+ if (!strcmp(argv[1], "quit"))
+ return (tk_op_push(sp, tkp, E_QUIT));
+ break;
+ case 'w':
+ if (!strcmp(argv[1], "write"))
+ return (tk_op_push(sp, tkp, E_WRITE));
+ if (!strcmp(argv[1], "writequit")) {
+ if (tk_op_push(sp, tkp, E_WRITE) != TCL_OK)
+ return (TCL_ERROR);
+ if (tk_op_push(sp, tkp, E_QUIT) != TCL_OK)
+ return (TCL_ERROR);
+ return (TCL_OK);
+ }
+ break;
+ }
+ (void)Tcl_VarEval(tkp->interp,
+ "tk_err {", argv[1], ": unknown event", "}", NULL);
+ return (TCL_OK);
+}
+
+/*
+ * tk_op_push --
+ * Push an event.
+ */
+static int
+tk_op_push(sp, tkp, et)
+ SCR *sp;
+ TK_PRIVATE *tkp;
+ e_event_t et;
+{
+ EVENT *evp;
+
+ CALLOC(sp, evp, EVENT *, 1, sizeof(EVENT));
+ if (evp == NULL)
+ return (TCL_ERROR);
+
+ evp->e_event = et;
+ TAILQ_INSERT_TAIL(&tkp->evq, evp, q);
+ return (TCL_OK);
+}
+
+/*
+ * tk_opt_init --
+ * Initialize the values of the current options.
+ *
+ * PUBLIC: int tk_opt_init __P((ClientData, Tcl_Interp *, int, char *[]));
+ */
+int
+tk_opt_init(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ OPTLIST const *op;
+ SCR *sp;
+ TK_PRIVATE *tkp;
+ int off;
+ char buf[20];
+
+ sp = __global_list->dq.cqh_first; /* XXX */
+
+ tkp = (TK_PRIVATE *)clientData;
+ for (op = optlist, off = 0; op->name != NULL; ++op, ++off) {
+ if (F_ISSET(op, OPT_NDISP))
+ continue;
+ switch (op->type) {
+ case OPT_0BOOL:
+ case OPT_1BOOL:
+ (void)Tcl_VarEval(tkp->interp, "set tko_",
+ op->name, O_ISSET(sp, off) ? " 1" : " 0", NULL);
+ break;
+ case OPT_NUM:
+ (void)snprintf(buf,
+ sizeof(buf), " %lu", O_VAL(sp, off));
+ (void)Tcl_VarEval(tkp->interp,
+ "set tko_", op->name, buf, NULL);
+ break;
+ case OPT_STR:
+ (void)Tcl_VarEval(tkp->interp,
+ "set tko_", op->name, " {",
+ O_STR(sp, off) == NULL ? "" : O_STR(sp, off),
+ "}", NULL);
+ break;
+ }
+ }
+ return (TCL_OK);
+}
+
+/*
+ * tk_opt_set --
+ * Set an options button.
+ *
+ * PUBLIC: int tk_opt_set __P((ClientData, Tcl_Interp *, int, char *[]));
+ */
+int
+tk_opt_set(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ ARGS *ap[2], a, b;
+ GS *gp;
+ SCR *sp;
+ int rval;
+ void (*msg) __P((SCR *, mtype_t, char *, size_t));
+ char buf[64];
+
+ gp = __global_list;
+ sp = gp->dq.cqh_first; /* XXX */
+
+ switch (argc) {
+ case 2:
+ a.bp = argv[1] + (sizeof("tko_") - 1);
+ a.len = strlen(a.bp);
+ break;
+ case 3:
+ a.bp = buf;
+ a.len = snprintf(buf, sizeof(buf),
+ "%s%s", atoi(argv[2]) ? "no" : "", argv[1]);
+ break;
+ default:
+ abort();
+ }
+ b.bp = NULL;
+ b.len = 0;
+ ap[0] = &a;
+ ap[1] = &b;
+
+ /* Use Tcl/Tk for error messages. */
+ msg = gp->scr_msg;
+ gp->scr_msg = tk_msg;
+
+ rval = opts_set(sp, ap, NULL);
+
+ gp->scr_msg = msg;
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tk_version --
+ * Display the version in Tcl/Tk.
+ *
+ * PUBLIC: int tk_version __P((ClientData, Tcl_Interp *, int, char *[]));
+ */
+int
+tk_version(clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ EXCMD cmd;
+ GS *gp;
+ SCR *sp;
+ int rval;
+ void (*msg) __P((SCR *, mtype_t, char *, size_t));
+
+ gp = __global_list;
+ sp = gp->dq.cqh_first; /* XXX */
+
+ msg = gp->scr_msg;
+ gp->scr_msg = tk_msg;
+
+ ex_cinit(&cmd, C_VERSION, 0, OOBLNO, OOBLNO, 0, NULL);
+ rval = cmd.cmd->fn(sp, &cmd);
+ (void)ex_fflush(sp);
+
+ gp->scr_msg = msg;
+ return (rval ? TCL_ERROR : TCL_OK);
+}
+
+/*
+ * tk_msg --
+ * Display an error message in Tcl/Tk.
+ *
+ * PUBLIC: void tk_msg __P((SCR *, mtype_t, char *, size_t));
+ */
+void
+tk_msg(sp, mtype, line, rlen)
+ SCR *sp;
+ mtype_t mtype;
+ char *line;
+ size_t rlen;
+{
+ TK_PRIVATE *tkp;
+ char buf[2048];
+
+ if (line == NULL)
+ return;
+
+ tkp = TKP(sp);
+ (void)snprintf(buf, sizeof(buf), "%.*s", (int)rlen, line);
+ (void)Tcl_VarEval(tkp->interp, "tk_err {", buf, "}", NULL);
+}
diff --git a/contrib/nvi/tk/tki.h b/contrib/nvi/tk/tki.h
new file mode 100644
index 0000000..206dacf
--- /dev/null
+++ b/contrib/nvi/tk/tki.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Keith Bostic. All rights reserved.
+ *
+ * See the LICENSE file for redistribution information.
+ *
+ * @(#)tki.h 8.6 (Berkeley) 4/27/96
+ */
+
+#include <tcl.h>
+#include <tk.h>
+
+typedef struct _tk_private {
+ Tcl_Interp *interp;/* Tcl interpreter cookie. */
+
+ /* Shared variables. */
+ int tk_cursor_row; /* Current cursor row. */
+ int tk_cursor_col; /* Current cursor col. */
+ int tk_ssize_row; /* Screen rows. */
+ int tk_ssize_col; /* Screen columns. */
+
+ struct termios orig; /* Original terminal values. */
+
+ CHAR_T ibuf[64]; /* Input keys. */
+ int ibuf_cnt; /* Number of input keys. */
+
+ /* Event queue. */
+ TAILQ_HEAD(_eventh, _event) evq;
+
+ int killersig; /* Killer signal. */
+#define INDX_HUP 0
+#define INDX_INT 1
+#define INDX_TERM 2
+#define INDX_WINCH 3
+#define INDX_MAX 4 /* Original signal information. */
+ struct sigaction oact[INDX_MAX];
+
+#define TK_LLINE_IV 0x0001 /* Last line is in inverse video. */
+#define TK_SCR_VI_INIT 0x0002 /* Vi screen initialized. */
+#define TK_SIGHUP 0x0004 /* SIGHUP arrived. */
+#define TK_SIGINT 0x0008 /* SIGINT arrived. */
+#define TK_SIGTERM 0x0010 /* SIGTERM arrived. */
+#define TK_SIGWINCH 0x0020 /* SIGWINCH arrived. */
+ u_int16_t flags;
+} TK_PRIVATE;
+
+extern GS *__global_list;
+#define TKP(sp) ((TK_PRIVATE *)((sp)->gp->tk_private))
+#define GTKP(gp) ((TK_PRIVATE *)gp->tk_private)
+
+/* Return possibilities from the keyboard read routine. */
+typedef enum { INP_OK=0, INP_EOF, INP_ERR, INP_INTR, INP_TIMEOUT } input_t;
+
+/* The screen line relative to a specific window. */
+#define RLNO(sp, lno) (sp)->woff + (lno)
+
+/* Some functions can be safely ignored until the screen is running. */
+#define VI_INIT_IGNORE(sp) \
+ if (F_ISSET(sp, SC_VI) && !F_ISSET(TKP(sp), TK_SCR_VI_INIT)) \
+ return (0);
+
+#include "tk_extern.h"
OpenPOWER on IntegriCloud