#!/usr/bin/rhswish -f

# Printer config tool
# (C) Copyright 1994 by Red Hat Software
# (C) Copyright 1995 by Michael Callahan

if {[catch set env(CONTROL_PANEL_LIB_DIR)] != 0} {
    set env(CONTROL_PANEL_LIB_DIR) /usr/lib/rhs/control-panel
}
if {[catch {source $env(CONTROL_PANEL_LIB_DIR)/dialog.tcl}] != 0} {
    puts "Couldn't load dialog.tcl"
    puts "Start from control-panel or set environment variable"
    puts "CONTROL_PANEL_LIB_DIR to the control-panel library dir."
    puts "(normally this is /usr/lib/rhs/control-panel)"
    exit 0
}
if {[catch {source $env(CONTROL_PANEL_LIB_DIR)/bindings.tcl}] != 0} {
    puts "Couldn't load bindings.tcl"
    puts "Start from control-panel or set environment variable"
    puts "CONTROL_PANEL_LIB_DIR to the control-panel library dir."
    puts "(normally this is /usr/lib/rhs/control-panel)"
    exit 0
}

#########################################################
## @@ Random Data

set printer_count 0
set delete_index ""
set trigger 0
set trigger_2 0

set printer_list "PostScript laserjet ljet2p ljet3 ljet4 ljetplus epson epsonc ibmpro jetp3852 deskjet djet500 djet500c bj10e bj200 cdeskjet cdjcolor cdjmono cdj500 cdj550"
set resolution_list "300x300 360x360 400x400 600x600 800x800"
set paper_size_list "letter legal ledger a3 a4"

set auto_printer ""
set auto_resolution ""
set auto_paper_size ""
set auto_flag "*auto*"
set auto_eof 0

set genfilter "$env(CONTROL_PANEL_LIB_DIR)/genfilter"
set filter_template "$env(CONTROL_PANEL_LIB_DIR)/filter-template"

#########################################################
## @@ User interface

frame .menuf -relief raised -borderwidth 2
menubutton .menuf.fsm -text "PrintTool" -menu .menuf.fsm.menu
menu .menuf.fsm.menu
.menuf.fsm.menu add command -label "Reload" -command menu_reload
.menuf.fsm.menu add separator
.menuf.fsm.menu add command -label "About" -command menu_about
.menuf.fsm.menu add separator
.menuf.fsm.menu add command -label "Quit" -command menu_quit
menubutton .menuf.nfs -text "lpd" -menu .menuf.nfs.menu
menu .menuf.nfs.menu
.menuf.nfs.menu add command -label "Restart lpd" -command menu_restart_lpd

pack .menuf.fsm .menuf.nfs -side left -in .menuf
tk_menuBar .menuf .menuf.fsm .menuf.nfs

label .header -font fixed -text "Printer Queues in /etc/printcap"

frame .main -relief sunken -borderwidth 2
listbox .list -font fixed -yscrollcommand ".sb set" -setgrid 1 -exportselection 0
scrollbar .sb -command ".list yview"
pack .list -side left -expand true -fill both -in .main
pack .sb -side left -fill y -in .main

frame .buttons
button .edit -text "Edit" -width 10 -command button_edit
button .add -text "Add" -width 10 -command button_add
button .delete -text "Delete" -width 10 -command button_delete
pack .edit .add .delete -side left -expand true -ipady 1 -padx 1c -in .buttons

pack .menuf -side top -fill x
# The following large padx is so that the header
# lines up properly with the stuff in the listbox
pack .header -side top -fill x
pack .main -side top -expand true -fill both -padx 4
pack .buttons -side top -fill x -padx 4 -pady 4

wm title . "BC/RHS Linux Print System Manager"
update
scan [wm geometry .] "%d%*c%d" xmin ymin
wm minsize . $xmin $ymin

bind .list <Double-Button-1> "
    .list select clear
    .list select from \[.list nearest %y\]
    button_edit
"

## End of main user interface
###########################################################
## @@ Random Functions

proc reload {} {
    global print_count printer_comments printer_entry
    global printer_names printer_type printer_info

    set print_count 0
    if {[catch {set fd [open "/etc/printcap" r]}] == 1} {
	# there is no /etc/printcap
	return
    }

    # We read the /etc/printcap file quickly into the arrays
    # printer_comments() and printer_entry().  printer_comments($i)
    # contains the comments which precede a given entry.  The special
    # line "##PRINTTOOL## <type> <info>" allows the printtool to
    # store extra information about the printer; <type> is one of the
    # allowed printer types, and <info> is a TCL list, saved in the
    # array printer_info.  

    set i 0
    set printer_comments(0) ""
    set printer_entry(0) ""
    set printer_type(0) ""
    set printer_info(0) ""
    while {[gets $fd s] != "-1"} {
	# Recognize comments and whitespace lines
	set cp [lindex $s 0]p
	if {[regexp "^\#" $cp] == 1 || [regexp {^[ 	]*$} $s] == 1} {
	    # Is it a special printtool line?
	    if {[regexp "^\\#\#PRINTTOOL\#\#" $cp] == 1} {
		set printer_type($i) [lindex $s 1]
		set printer_info($i) [lrange $s 2 [expr [llength $s]-1]]
	    } else {
		set printer_comments($i) "$printer_comments($i)$s\n"
	    }
	    continue
	}
	
	# If we get to here we have a printer definition
	# Read it in--keep reading until we reach a line that doesn't
	# end in the continuation mark, or EOF
	set printer_entry($i) "$s\n"
	while {[regexp "\\\\$" $s] && [gets $fd s] != "-1"} {
	    set printer_entry($i) "$printer_entry($i)$s\n"
	}
	incr print_count
	incr i
	set printer_comments($i) ""
	set printer_entry($i) ""
	set printer_type($i) ""
	set printer_info($i) ""
    }

    close $fd

    # NB: the printer_entry and printer_comments arrays have different
    # array bounds.  printer_entry is defined from 0 to $print_count-1.
    # printer_comments is defined from 0 to $print_count.
    # printer_comments($print_count) consists of comments following
    # the last printer.

    # Now go through to examine each entry
    for {set i 0} {$i < $print_count} {incr i} {
	# Canonicalize entry
	set e $printer_entry($i)
	regsub -all "\\\\\n\[ \t\]*" $e " " e
	regsub -all ":\[ \t\]*:" $e ":" e
	regsub "\[ \t\]*\n\$" $e "" e
	set printer_entry($i) $e

	# First field gives the printer names
	regexp {^([^:]*):} $printer_entry($i) bogus printer_names($i)

	# Fix printer_type
	if {$printer_type($i) == ""} {
	    set printer_type($i) UNKNOWN
	} else {
	    # Make sure this type is known
	    if {[info procs "$printer_type($i)_summaryline"] == ""} {
		set printer_type($i) UNKNOWN
		set printer_info($i) {}
	    }
	}
	if {$printer_type($i) == "UNKNOWN"} {
	    set res [guess_printer_type $i]
	    if {[llength $res] > 0} {
		set printer_type($i) [lindex $res 0]
		set printer_info($i) [lrange $res 1 [expr [llength $res]-1]]
	    }
	}
    }
}

proc guess_printer_type {i} {
    global print_count printer_comments printer_entry
    global printer_names printer_type printer_info

    if {[printcap_field $i "rm=" ""] != "" && \
	    [printcap_field $i "rp=" ""] != ""} {
	return {REMOTE}
    }

    set spool_dir [printcap_field $i "sd=" ""]
    set i_filter [printcap_field $i "if=" ""]
    if {$i_filter == "$spool_dir/filter"} {
	# possibly a filter generated by this tool
	if {[catch {set fd [open $i_filter "r"]}] == 1} {
	    return {}
	}
	gets $fd s
	gets $fd s
	gets $fd s
	if {[regexp "^DEVICE=\(.*\)\$" $s dummy auto_printer] != 1} {
	    close $fd
	    return {}
	}

	gets $fd s
	if {[regexp "^RESOLUTION=\(.*\)\$" $s dummy auto_resolution] != 1} {
	    close $fd
	    return {}
	}

	gets $fd s
	if {[regexp "^PAPERSIZE=\(.*\)\$" $s dummy auto_paper_size] != 1} {
	    close $fd
	    return {}
	}

	gets $fd s
	if {[regexp "^SENDEOF=\(.*\)\$" $s dummy auto_eof] != 1} {
	    close $fd
	    return {}
	}

	close $fd
	return [list "LOCAL" $auto_printer $auto_resolution $auto_paper_size \
		    $auto_eof]
    }
    return {}
}

proc printcap_field {i field default} {
    global printer_entry
    if {[regexp ":$field\(\[^:\]*\):" $printer_entry($i) dummy val] == 1} {
	return $val
    } else {
	return $default
    }
}

proc set_printcap_field {i field val} {
    global printer_entry
    if {[regsub ":$field\[^:\]*:" $printer_entry($i) ":$field$val:" \
	     printer_entry($i)] == 0} {
	# not there already: add to end (recall $printer_entry($i) ends w/":")
	set printer_entry($i) "$printer_entry($i)$field$val:"
    }
}

proc printcap_switch {i field} {
    global printer_entry
    return [regexp ":$field:" $printer_entry($i)]
}

proc set_printcap_switch {i field val} {
    global printer_entry
    if {$val == 0} {
	regsub ":$field:" $printer_entry($i) ":" printer_entry($i)
    } else {
	if {[regexp ":$field:" $printer_entry($i)] == 0} {
	    set printer_entry($i) "$printer_entry($i)$field:"
	}
    }
}

proc redisplay {} {
    global print_count printer_names printer_type

    .list delete 0 end
    for {set i 0} {$i < $print_count} {incr i} {
	.list insert end [format "%-10s  %s" $printer_names($i) \
			      [$printer_type($i)_summaryline $i] ]
    }
}

# Each printer type should export functions
#  TYPE_summaryline {i}  giving a summary for the main printer list
#  TYPE_name {}  giving a readable name for the type
#  TYPE_addpanel {w i} adds the configuration entries to the edit panel
#  TYPE_updateentry {w i} pulls configuration options out of the edit panel
#  TYPE_setup {i}  doing whatever extra type-specific setup is necessary
# printer_type_list is a list of printer types which should be presented
# to the user -- ie everything but UNKNOWN

set printer_type_list {LOCAL REMOTE}

proc UNKNOWN_summaryline {i} { return "type unrecognized" }
proc UNKNOWN_name {} { return "unknown printer type--should not appear" }
proc UNKNOWN_addpanel {w i} {
    puts "UNKNOWN_addpanel called--shouldn't happen"
}
proc UNKNOWN_updateentry {w i} { 
    puts "UNKNOWN_updateentry called--shouldn't happen" 
}
proc UNKNOWN_setup {i} { puts "UNKNOWN_setup called--shouldn't happen" }

proc LOCAL_summaryline {i} { 
    global printer_info

    set info $printer_info($i)
    set printer "local printer"
    if {[llength $info] >= 1} {
	set printer [lindex $info 0]
    }
    set port [printcap_field $i {lp=} {unspecified device}]
    return "$printer on $port"
}
proc LOCAL_name {} { return "Local Printer" }

proc LOCAL_addpanel {w i} {
    global printer_names printer_type printer_info printer_entry
    global printer_comments printer_type_list
    global suppress_headers
    global auto_printer auto_resolution auto_paper_size auto_flag auto_eof

    set traversal_list ""

    label $w.l8 -text "Printer Device" -anchor w
    entry $w.v8 -font fixed -relief sunken -borderwidth 2
    $w.v8 insert 0 [printcap_field $i "lp=" ""]
    lappend traversal_list $w.v8

    frame $w.fl9
    label $w.l9 -text "Input Filter" -anchor w
    button $w.autofilter -text "Select" -command "LOCAL_select_filter $w.v9"
    pack $w.l9 -side left -in $w.fl9
    pack $w.autofilter -side right -in $w.fl9

    entry $w.v9 -font fixed -relief sunken -borderwidth 2
    $w.v9 insert 0 [printcap_field $i "if=" ""]
    lappend traversal_list $w.v9

    entry $w.l10 -font fixed -relief flat -state disabled
    checkbutton $w.v10 -text "Suppress Headers" -anchor w \
	-variable suppress_headers
    set suppress_headers [printcap_switch $i "sh"]

    pack $w.l8 $w.fl9 $w.l10 -side top -fill x -in $w.f1
    pack $w.v8 -pady 1 -side top -expand true -fill x -in $w.f2
    pack $w.v9 -pady 5 -side top -expand true -fill x -in $w.f2
    pack $w.v10 -pady 1 -side top -expand true -fill x -in $w.f2

    # fill in defaults for select_filter panel
    set info $printer_info($i)
    if {[llength $info] >= 4} {
	set auto_printer [lindex $info 0]
	set auto_resolution [lindex $info 1]
	set auto_paper_size [lindex $info 2]
	set auto_eof [lindex $info 3]
    } else {
	set auto_printer ""
	set auto_resolution ""
	set auto_paper_size ""
	set auto_eof ""
    }

    return $traversal_list
}

proc LOCAL_select_filter {e} {
    global trigger_2
    global printer_list resolution_list paper_size_list
    global auto_printer auto_resolution auto_paper_size auto_flag auto_eof

    toplevel .sf
    wm withdraw .sf
    wm title .sf "Configure Filter"

    frame .sf.f1
    frame .sf.f2
    frame .sf.f3
    frame .sf.f4
    frame .sf.f5

    label .sf.l1 -text "Printer Type" -anchor e -width 12
    label .sf.l2 -text "Resolution" -anchor e -width 12
    label .sf.l3 -text "Paper Size" -anchor e -width 12

    menubutton .sf.mb1 -bitmap dropdown -menu .sf.mb1.m1 -relief raised
    menubutton .sf.mb2 -bitmap dropdown -menu .sf.mb2.m2 -relief raised
    menubutton .sf.mb3 -bitmap dropdown -menu .sf.mb3.m3 -relief raised

    menu .sf.mb1.m1
    foreach x $printer_list {
	.sf.mb1.m1 add command -label $x -command ".sf.sf1 delete 0 end; .sf.sf1 insert 0 $x"
    }
    menu .sf.mb2.m2
    foreach x $resolution_list {
	.sf.mb2.m2 add command -label $x -command ".sf.sf2 delete 0 end; .sf.sf2 insert 0 $x"
    }
    menu .sf.mb3.m3
    foreach x $paper_size_list {
	.sf.mb3.m3 add command -label $x -command ".sf.sf3 delete 0 end; .sf.sf3 insert 0 $x"
    }

    entry .sf.sf1 -relief sunken -font fixed -width 15
    entry .sf.sf2 -relief sunken -font fixed -width 15
    entry .sf.sf3 -relief sunken -font fixed -width 15

    .sf.sf1 insert 0 $auto_printer
    .sf.sf2 insert 0 $auto_resolution
    .sf.sf3 insert 0 $auto_paper_size

    pack .sf.l1 .sf.mb1 -side left -in .sf.f1
    pack .sf.sf1 -side left -expand true -fill x -in .sf.f1
    pack .sf.l2 .sf.mb2 -side left -in .sf.f2
    pack .sf.sf2 -side left -expand true -fill x -in .sf.f2
    pack .sf.l3 .sf.mb3 -side left -in .sf.f3
    pack .sf.sf3 -side left -expand true -fill x -in .sf.f3

    checkbutton .sf.c1 -text "Send EOF (\\014)" \
	-variable auto_eof -offvalue "" -onvalue 1
    pack .sf.c1 -side top -in .sf.f4

    button .sf.b1 -text "OK" -width 10 -command "set trigger_2 1"
    button .sf.b2 -text "Cancel" -width 10 -command "set trigger_2 0"
    pack .sf.b1 .sf.b2 -side left -expand true -ipady 1 -in .sf.f5

    pack .sf.f1 .sf.f2 .sf.f3 -side top -expand true -fill x -in .sf
    pack .sf.f4 .sf.f5 -side top -expand true -fill x -pady 3 -in .sf

    center_dialog .sf
    grab set .sf
    update
    tkwait variable trigger_2
    if {$trigger_2 == 1} {
	set auto_printer [.sf.sf1 get]
	set auto_resolution [.sf.sf2 get]
	set auto_paper_size [.sf.sf3 get]
	$e delete 0 end
	$e insert 0 $auto_flag
    }
    destroy .sf
    return $trigger_2
}

proc LOCAL_updateentry {w i} {
    global printer_info
    global auto_printer auto_resolution auto_paper_size auto_flag auto_eof
    global suppress_headers

    set_printcap_field $i "lp=" [$w.v8 get]
    set_printcap_field $i "if=" [$w.v9 get]
    set_printcap_switch $i "sh" $suppress_headers
    if {[$w.v9 get] == $auto_flag} {
	set printer_info($i) [list $auto_printer $auto_resolution \
				  $auto_paper_size $auto_eof]
    }
}

proc LOCAL_setup {i} {
    global auto_printer auto_resolution auto_paper_size auto_flag auto_eof
    global genfilter filter_template

    set i_filter [printcap_field $i "if=" ""]
    if {$i_filter == $auto_flag} {
	set spool_dir [printcap_field $i "sd=" ""]
	set i_filter "$spool_dir/filter"
	set_printcap_field $i "if=" $i_filter
	catch {exec rm -f $i_filter}
	catch {exec $genfilter $auto_printer $auto_resolution $auto_paper_size $auto_eof < $filter_template > $i_filter}
	catch {exec chmod 755 $i_filter}
    }
}

proc REMOTE_summaryline {i} { 
    set queue [printcap_field $i "rp=" "lp"]
    set host [printcap_field $i "rm=" "(unspecified host)"]
    return "lpd queue $queue on $host"
}

proc REMOTE_name {} { return "Remote Unix (lpd) Queue" }

proc REMOTE_addpanel {w i} {
    set traversal_list ""

    label $w.l5 -text "Remote Host" -anchor w
    entry $w.v5 -font fixed -relief sunken -borderwidth 2
    $w.v5 insert 0 [printcap_field $i "rm=" ""]
    lappend traversal_list $w.v5

    label $w.l6 -text "Remote Queue" -anchor w
    entry $w.v6 -font fixed -relief sunken -borderwidth 2
    $w.v6 insert 0 [printcap_field $i "rp=" ""]
    lappend traversal_list $w.v6

    pack $w.l5 $w.l6 -side top -fill x -in $w.f1
    pack $w.v5 $w.v6 -pady 1 -side top -expand true -fill x -in $w.f2

    return $traversal_list
}

proc REMOTE_updateentry {w i} {
    set_printcap_field $i "rm=" [$w.v5 get]
    set_printcap_field $i "rp=" [$w.v6 get]
}
proc REMOTE_setup {i} {}

proc write_printcap {} {
    global print_count printer_comments printer_entry
    global printer_info printer_type
    global delete_index

    set fd [open "/etc/printcap" w]

    for {set i 0} {$i < $print_count} {incr i} {
	if {$i == 0 || $i != $delete_index} {
	    puts -nonewline $fd $printer_comments($i)
	}
	if {$i != $delete_index} {
	    if {$printer_type($i) != "UNKNOWN"} {
		puts $fd "\#\#PRINTTOOL\#\# $printer_type($i) $printer_info($i)"
	    }
	    # De-canonicalize entry
	    set entry $printer_entry($i)
	    regsub -all ":" $printer_entry($i) ":\\\n\t:" entry
	    regsub "\\\\\n\t:\$" $entry "\n" entry
	    puts -nonewline $fd $entry
	}
    }
    puts -nonewline $fd $printer_comments($i)

    close $fd
    set delete_index ""
}

proc sync {} {
    write_printcap
    reload
    redisplay
}

proc get_selected_index {} {
    return [.list curselection]
}

proc bind_entries_for_traversal {l} {
    set count [llength $l]
    lappend l [lindex $l 0]
    for {set i 0} {$i < $count} {incr i} {
	set from [lindex $l $i]
	set to [lindex $l [expr $i + 1]]
	set_emacs_entry_bindings $from
	bind $from <Return> "focus $to"
	bind $from <Tab> "focus $to"
	bind $to <Shift-Tab> "focus $from"
    }
}

proc edit_entry {i} {
    global print_count printer_names printer_entry printer_type printer_type_list
    global trigger

    if {$printer_type($i) == "UNKNOWN"} {
	rhs_error_dialog \
"This printer was not created by the 
Print System Manager.  You can remove 
it using this tool but not edit it."
	return 0
    }

    toplevel .e
    wm withdraw .e
    wm title .e "Edit [$printer_type($i)_name] Entry"

    frame .e.f1
    frame .e.f2
    frame .e.f3

    set traversal_list ""

    label .e.l1 -text "Names (name1|name2|...)" -anchor w
    entry .e.v1 -font fixed -relief sunken -borderwidth 2
    .e.v1 insert 0 $printer_names($i)
    lappend traversal_list .e.v1

    label .e.l2 -text "Spool Directory" -anchor w
    entry .e.v2 -font fixed -relief sunken -borderwidth 2
    .e.v2 insert 0 [printcap_field $i "sd=" ""]
    lappend traversal_list .e.v2

    label .e.l3 -text "File Limit in Kb (0 = no limit)" -anchor w
    entry .e.v3 -font fixed -relief sunken -borderwidth 2
    .e.v3 insert 0 [printcap_field $i "mx%" "0"]
    lappend traversal_list .e.v3

    pack .e.l1 .e.l2 .e.l3 -side top -fill x -in .e.f1

    pack .e.v1 .e.v2 .e.v3 -pady 1 -side top -expand true -fill x -in .e.f2

    frame .e.buttons
    button .e.b1 -text "OK" -width 10 -command "set trigger 1"
    pack .e.b1 -side left -expand true -ipady 1 -in .e.buttons
    button .e.b2 -text "Cancel" -width 10 -command "set trigger 0"
    pack .e.b2 -side left -expand true -ipady 1 -in .e.buttons

    pack .e.buttons -side bottom -expand true -fill x -padx 4 -pady 4 -in .e
    pack .e.f3 -side bottom -expand true -fill x

    set traversal_list [concat $traversal_list \
			    [$printer_type($i)_addpanel .e $i]]
    bind_entries_for_traversal $traversal_list

    pack .e.f1 -side left -fill both -padx 2 -pady 1 -in .e
    pack .e.f2 -side left -expand true -fill both -padx 2 -pady 1 -in .e

    center_dialog .e
    grab set .e
    update
    scan [wm geometry .e] "%d%*c%d" xmin ymin
    wm minsize .e $xmin $ymin
    wm maxsize .e 10000 $ymin
    tkwait variable trigger

    if {$trigger == 1} {
	set printer_names($i) [.e.v1 get]
	regsub {^[^:]*:} $printer_entry($i) "[.e.v1 get]:" printer_entry($i)
	
	set_printcap_field $i "sd=" [.e.v2 get]
	set_printcap_field $i "mx%" [.e.v3 get]

	$printer_type($i)_updateentry .e $i
    }

    destroy .e
    return $trigger
}

proc edit_entry_aux {i} {
    global printer_type

    set res [edit_entry $i]

    if {$res == 1} {
	# make spool directory
	set spool_dir [printcap_field $i "sd=" ""]
	catch {exec mkdir -p $spool_dir}
	catch {exec chown root.lp $spool_dir}
	catch {exec chmod 755 $spool_dir}

	# do type-specific setup
	$printer_type($i)_setup $i

	sync
    }

    return $res
}

proc printer_type_dialog {} {
    global type_name trigger_3
    global printer_type_list
    
    # MJC
    # display list of printer types

    .list select clear

    toplevel .pt
    wm withdraw .pt
    wm title .pt "Add a Printer Entry"

    label .pt.l1 -text "Printer type:" -anchor w
    pack .pt.l1 -side top
    foreach t $printer_type_list {
	set readabletypeproc ${t}_name
	radiobutton .pt.t_$t -text [$readabletypeproc] -variable type_name \
	    -value $t -anchor w 
	pack .pt.t_$t -side top -fill x -padx 2
    }
    set type_name [lindex $printer_type_list 0]

    frame .pt.buttons
    button .pt.ok -text "OK" -width 10 -command "set trigger_3 1"
    pack .pt.ok -side left -expand true -ipady 1 -pady 3 -in .pt.buttons
    button .pt.cancel -text "Cancel" -width 10 -command "set trigger_3 0"
    pack .pt.cancel -side left -expand true -ipady 1 -pady 3 -in .pt.buttons

    pack .pt.buttons -side top

    center_dialog .pt
    grab set .pt
    update
    scan [wm geometry .pt] "%d%*c%d" xmin ymin
    wm minsize .pt $xmin $ymin
    wm maxsize .pt 10000 $ymin
    set trigger_3 0
    tkwait variable trigger_3

    destroy .pt

    if {$trigger_3 == 1} {
	return $type_name
    }

    return {}
}
   

## End of random functions
##############################################
## @@ User Interface callback functions

proc menu_about {} {

    rhs_info_dialog "
This tool allows you to set up simple printers easily.

The default printer is the first one listed.  To change
this you will have to edit /etc/printcap and move the
apropriate entry to the head of the list.

The filters are set up such that the input should be
PostScript, and it will be translated to the proper
printer language for your printer.  This means you
can not simply type \"lpr text_file\".  It must first
be converted to PostScript.  The right way is:

nenscript text_file

to print to the default printer.

The filters use ghostscript; make sure it is installed.
"
}

proc button_add {} {
    global print_count printer_names printer_entry printer_comments
    global printer_info printer_type

    set type [printer_type_dialog]
    # user may have selected "Cancel"
    if {$type == ""} {
	return
    }

    # First find a candidate lpX
    # (Make first printer added "lp")
    set done 0
    set num 0
    if {$print_count == 0} {
	set lpx "lp"
	set done 1
    }
    while {$done == 0} {
	set lpx "lp$num"
	set done 1
	for {set i 0} {$i < $print_count} {incr i} {
	    if {[regexp $lpx $printer_names($i)] == 1} {
		set done 0
		break
	    }
	}
	incr num
    }

    set i $print_count
    incr print_count

    set printer_names($i) "$lpx"
    set printer_type($i) $type
    set printer_info($i) {}
    set printer_entry($i) "$lpx:sd=/var/spool/lpd/$lpx:mx%0:"
    set printer_comments($print_count) ""

    if {[edit_entry_aux $i] != 1} {
	incr print_count -1
    }
}

proc button_delete {} {
    global printer_names spool_dir delete_index

    set i [.list curselection]
    if {$i == ""} {
	rhs_error_dialog "No Printer Selected"
	return
    }

    set res [rhs_continue_dialog "Delete $printer_names($i) from /etc/printcap?"]
    if {$res == 1} {
	return
    }

    set spool_dir [printcap_field $i "sd=" ""]
    if {$spool_dir != ""} {
	rhs_info_dialog "Please remember to remove the spool directory:\n\n$spool_dir"
    }

    set delete_index $i
    # sync writes /etc/printcap first, so this will do
    sync
}

proc button_edit {} {
    set i [get_selected_index]
    if {$i == ""} {
	return
    }

    edit_entry_aux $i
}

proc menu_restart_lpd {} {
    catch {exec /etc/rc.d/init.d/lpd stop}
    catch {exec /etc/rc.d/init.d/lpd start}
}

proc menu_quit {} {
    # We could sync here but we should always be synced
    exit 0
}

proc menu_reload {} {
    global selected_hint

    .list delete 0 end
    update idletasks

    # We don't need to (and should not) write out printcap
    # since we should always be synced, and the goal
    # is really to pick up any external changes

    reload
    redisplay
}

## End of user interface callback functions
#############################################
## @@ main program

tk_listboxSingleSelect .list

catch {source printtool-server}

# We can't call sync right away or /etc/fstab will get clobbered

catch {exec /bin/cp -f /etc/printcap /etc/printcap.bak}
reload
write_printcap
redisplay

