diff options
author | Peter Wemm <peter@FreeBSD.org> | 1996-11-01 06:45:43 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 1996-11-01 06:45:43 +0000 |
commit | b8ba871bd943582ed54f83888569d65b356469bd (patch) | |
tree | 88f923c9c0be2e2a225a9b21716fd582de668b42 /contrib/nvi/tk | |
parent | f1460870b9b650c789026a4fb571ce2634243b10 (diff) |
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>
Notes
Notes:
svn path=/vendor/nvi/dist/; revision=19304
Diffstat (limited to 'contrib/nvi/tk')
-rw-r--r-- | contrib/nvi/tk/init.tcl | 1096 | ||||
-rw-r--r-- | contrib/nvi/tk/tk_funcs.c | 346 | ||||
-rw-r--r-- | contrib/nvi/tk/tk_main.c | 423 | ||||
-rw-r--r-- | contrib/nvi/tk/tk_read.c | 207 | ||||
-rw-r--r-- | contrib/nvi/tk/tk_screen.c | 86 | ||||
-rw-r--r-- | contrib/nvi/tk/tk_term.c | 169 | ||||
-rw-r--r-- | contrib/nvi/tk/tk_util.c | 250 | ||||
-rw-r--r-- | contrib/nvi/tk/tki.h | 64 |
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 000000000000..78c5a115c0a7 --- /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 000000000000..be2b0d96ea09 --- /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 000000000000..c2f34e7b2d9f --- /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 000000000000..b5cfab71c7e2 --- /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 000000000000..e1090930ba23 --- /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 000000000000..18299a28ae77 --- /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 000000000000..096fa7bb3eba --- /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 000000000000..206dacf5d73b --- /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" |