#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"

set progname xatv-setup 
set version 1.0
set credit "24 Jan 2007 Masaki Shinomiya <shino@pos.to>" ;# version 0.9
#set credit "23 Jan 2007 Masaki Shinomiya <shino@pos.to>" ;# version 0.9
#set credit " 8 Nov 2006 Masaki Shinomiya <shino@pos.to>" ;# version 0.8
#set credit "11 Nov 2006 Masaki Shinomiya <shino@pos.to>" ;# version 0.7
#set credit " 8 Nov 2006 Masaki Shinomiya <shino@pos.to>" ;# version 0.6
#set credit " 7 Nov 2006 Masaki Shinomiya <shino@pos.to>" ;# version 0.5
#set credit " 1 May 2005 Masaki Shinomiya <shino@pos.to>" ;# version 0.4

set verbose 0

set sysconfdir /etc
set datadir /usr/share
set tmpdir /var/tmp
set pkgdatadir [file join $datadir xawtv/xawtv-setup] 
set configfile [file join $sysconfdir modules.conf]
if [ file exists [file join $sysconfdir modprobe.conf] ] { set configfile [file join $sysconfdir modprobe.conf] }
set msgdir  $pkgdatadir
set cardlistdir   $pkgdatadir

# files are in current directory
if [file exists ./ja.msg] { set msgdir {.} }
if [file exists ./CARDLIST.bttv] { set cardlistdir {.} }

set logfile [file join $tmpdir $progname.tmp]

#set kernelsourcedir /usr/src/linux
#set cardlistfile [file join $kernelsourcedir Documentation/video4linux/bttv/CARDLIST]
#set tunerh [file join $kernelsourcedir drivers/media/video/tuner.h]

set tvwidth 380
wm geometry . +$tvwidth+0 

set supported_drivers {bttv saa7134 cx88 em28xx} 
set unsupported_drivers {ivtv}
set all_drivers [linsert $supported_drivers end $unsupported_drivers] 

set mwn {}
set nowitem {}
set oldstatus {}

# --debug option
if  [ info exists  env(DEBUG) ] { set verbose $env(DEBUG) }
set arg1 [lindex $argv 0]
switch -- $arg1 {
    --debug -
    -debug  { set verbose 1 }
}

# Try requiring msgcat (Tcl 8.1 and later)
set problem [catch {package require msgcat} err]
if {!$problem} {
    set problem [catch {::msgcat::mcload $msgdir} err]
}
if {$problem} {
    debug "$problem - $err"
    # leave it English
    proc m { str } { return $str }
} else {
    proc m { str } { ::msgcat::mc $str }
}
set help(opening) "[m {A GUI tool for configuration of}]\n[m {TV capture board drivers}]\n"

proc main_window { wn } {
  global mwn f progname version credit
  global lists entries nums
  global itembox nowitem statusline

  frame $mwn.f1

  # Buttons
  frame $mwn.f1.f6
  pack [button $mwn.f1.f6.b1 -text [m {Try}] -command load_driver] -side left
  pack [button $mwn.f1.f6.b2 -text [m {Save}] -command write_conf] -side left
  pack [button $mwn.f1.f6.b3 -text [m {End}] -command main_exit] -side right
  pack $mwn.f1.f6 -side bottom

  # titles
  pack [label $mwn.f1.l1 -text "$progname Ver.$version"]
  #pack [message $mwn.f1.l2 -text $credit -width 200]

  frame $mwn.f1.f1
  pack [label $mwn.f1.f1.l1 -text {Device} -width 6] -side left
  pack [entry $mwn.f1.f1.t1 -textvariable entries(device) -width 12] -side left
  #if { [llength $lists(device)] == 1} {
  #}
  pack $mwn.f1.f1

  frame $mwn.f1.f2
  pack [label $mwn.f1.f2.l1 -text {Driver} -width 6] -side left
  pack [entry $mwn.f1.f2.t1 -textvariable entries(driver) -width 12] -side left
  pack $mwn.f1.f2

  frame $mwn.f1.f3
  pack [label $mwn.f1.f3.l1 -text {Card} -width 6] -side left
  pack [entry $mwn.f1.f3.t1 -textvariable entries(card) -width 12] -side left
  pack $mwn.f1.f3

  frame $mwn.f1.f4
  pack [label $mwn.f1.f4.l1 -text {Tuner} -width 6] -side left
  pack [entry $mwn.f1.f4.t1 -textvariable entries(tuner) -width 12] -side left
  pack $mwn.f1.f4

  frame $mwn.f1.f5
  pack [checkbutton $mwn.f1.f5.c1 -variable entries(ntsc) -text {ntsc=j} -width 12] -side right
  pack $mwn.f1.f5

  # Status line
  set statusline $mwn.f1.statusline
  pack [message $statusline -text {} -width 180] -anchor w

  # list box
  frame $mwn.f6
  set itembox $mwn.f6.lb1
  pack [listbox $itembox -yscrollcommand "$mwn.f6.sb1 set" -width 36] -fill both  -expand yes -side left
  pack [scrollbar $mwn.f6.sb1 -command "$itembox yview"] -fill y -side left
  pack $mwn.f1 -side left -fill y -expand no
  pack $mwn.f6 -side left -fill both -expand yes

  # initialize
  initial_entry

  # binding
  bind $mwn.f1.l1 <ButtonRelease-1> { initial_entry }
  bind $mwn.f1.f1.t1 <FocusIn> {fill_list "device"}
  bind $mwn.f1.f2.t1 <FocusIn> {fill_list "driver"}
  bind $mwn.f1.f3.t1 <FocusIn> {fill_list "card"}
  bind $mwn.f1.f4.t1 <FocusIn> {fill_list "tuner"}
}

proc main_exit {} {
	global mwn f
	global configfile modified written
  if [modified] {
      if {[warn "[m {Exit without writing}] $configfile.
[m {You may loose the configuration when next bootup.}]\n[m {Is it OK?}]"] \
	 != "yes" } return
  }

	if { "$mwn" == "" } { destroy . } else { destroy $mwn }
}

proc debug { msg } {
	global verbose progname
	if $verbose {puts "$progname:debug:$msg"}
}

proc status { msg } {
	global mwn statusline oldstatus
	if { "$msg" == "$oldstatus" } { return }
	set oldstatus $msg
	if {[info exists statusline] && [winfo exists $statusline]} {
		$statusline configure -text "$msg"
		update
	}
	if { "$msg" != "" } { debug $msg }
}

proc error { msg } {
	global mwn progname
	tk_messageBox -icon error -message $msg -parent . -title "$progname error"
}

proc warn { msg } {
  global mwn progname
  return [tk_messageBox -type {yesno} -default {no} -icon {warning} \
	-message $msg -parent {.} -title "$progname warning"]
}

proc listname { name } {
    global entries
    set driver $entries(driver)
    if { "$name" == {tuner} } {
      switch -glob -- $driver {
	{bttv*}	   -
	{saa7134*} -
	{cx88*}	   -
	{em28xx*}	-
	{ivtv*}	{ return {tuner} }
	default { return {card_none} }
      }
    }
    if { "$name" != {card} } { return $name }
    switch -glob -- $driver {
	{bttv*}	{ set d {bttv} }
	{saa7134*} { set d {saa7134} }
	{cx88*} { set d {cx88} }
	{em28xx*} {set d {em28xx} }
	{ivtv*}	{ set d {ivtv} }
	default { set d {none} }
    }
    return "card_$d"
}

proc fill_list { name } {
  global mwn f
  global lists entries nums itembox nowitem
  $itembox delete 0 end
  set nowitem {}
  bind $itembox <ButtonRelease-1> {}
  if {[llength $lists([listname $name])] == 0 } {
	$itembox insert end [m "No entries"]
	return
  }
  foreach line $lists([listname $name]) {
		$itembox insert end $line
  }
  set nowitem $name
  get_nums
  if { "$nums(driver)" == {ivtv} } {
	status "ivtv is not supported by xawtv"
  }
  bind $itembox <ButtonRelease-1> {
      if { "$nowitem" != {}  } {
	enter_entry [$itembox get [$itembox curselection]] $nowitem
      }
  }
}

proc enter_entry { newentry item } {
  global entries supported_drivers
  global lists driver card tuner
  global modified written
  if { "$item" == {} } { return }
  set old $entries($item)
  set new [lindex [split $newentry { }] 0]
  if { "$new" != "$old" } {
    set entries($item) $new
    switch -- $item {
	{device} {
		foreach i {driver card tuner} {
			set ${i}($old) $entries($i)
		}
		recall_entries $new
	}
	{driver} {
		 set modified 1
  		 foreach i {card tuner} {
			set entries($i) {}
		}
	}
	default	{
		set modified 1
		set dev $entries(device)
		set drv $entries(driver)
		set ${item}($dev) $new
		debug "$drv [driver_options $drv]"
	}
    }
  }
}

proc log { msg } {
    global mwn f
    global itembox nowitem
    if { "$msg" == {} } return
    if { "$nowitem" != {} } {
	set nowitem {}
	$itembox delete 0 end
	foreach i {f1 f2 f3 f4} {
	    $mwn.f1.$i.t1 selection clear  
	}
    }
    foreach line  [split $msg \n] {
	$itembox insert end $line
    }
    $itembox see end
    debug $msg
}

proc help { item } {
    global mwn f
    global progname version credit help
    global itembox nowitem
    #if { "$nowitem" != {} } {
	set nowitem {}
	$itembox delete 0 end
#	foreach i {f1 f2 f3 f4} {
#	    if [info exists $mwn.f1.$i.t1 ] {
#		 $mwn.f1.$i.t1 selection clear
# }  
#	}
    #}
    $itembox insert end "$progname $version" 
    $itembox insert end $credit
    if [info exists help($item)] {
      help_append $help($item)
    }
}

proc help_append { msg } {
    global itembox
    if { "$msg" == {} } return
    foreach line  [split $msg \n] {
	$itembox insert end $line
    }
}

proc get_nums {} {
   global lists entries nums itembox nowitem
   global device driver card tuner
   foreach i {device driver card tuner} {
	set nums($i) [lindex [split $entries($i) { }] 0]
	switch -- $i {
	  {device} { set dev $nums($i) }
	  {driver} {
		set drv $nums($i)
		set driver($dev)  $drv
		 }
	  {default} {
		set ${i}($dev) $nums($i)
		set ${i}($drv) $nums($i)
		}
	}
	if { "$nums($i)" != {} && $i == $nowitem } {
	    set index [lsearch -glob $lists([listname $i]) "$nums($i) *"]
	    if { $index >= 0 } {
		$itembox see $index
		$itembox selection set $index $index
	    }
	}
   }
}

proc device_list {} {
    set devices {}
    set devicelist {}
    foreach i {"" 0 1 2 3 4 5 6 7 8 9} {
        set device /dev/video$i
	if { [catch {exec sh -c "test -L $device"}] == 0 }  {
	    debug "$device is a symlink"
        } elseif { [catch {exec sh -c "test -c $device"}] == 0 }  {
            lappend devices $device 
	    debug "$device found"
        }
    }
    foreach device $devices {
       set line ""
       catch {set line [exec sh -c "v4l-info $device 2> /dev/null | grep card"]}
       set cardname ""
       regexp \".\[^\"\]+\" $line cardname
       set cardfound [string trim $cardname \"]
       if { "$cardfound" == "" } { set cardfound Unkown }
       set card($device) $cardfound
       lappend devicelist "$device $cardfound"
    }
    return $devicelist
}

proc driver_list {} {
    set driverlist {"none "}
    set command {/sbin/modprobe -l}
    set lines [exec sh -c $command]
    set lines [split $lines \n]
    foreach line $lines {
	if { [regexp {/media/video.*/(bttv)\.k?o} $line dummy driver] || \
	     [regexp {/media/video.*/(saa7134)\.k?o} $line dummy driver] || \
	     [regexp {/media/video.*/(cx88[^-]*)\.k?o} $line dummy driver] || \
	     [regexp {/media/video.*/(em28xx.*)\.k?o} $line dummy driver]  } {
	    set driver [file tail $driver]
	    lappend driverlist "$driver "
	}
    }
    return $driverlist
}

proc card_list { cardlistfile } {
  debug "reading $cardlistfile"
    set cardlist {}
  set keyword {}
  #if [regexp bttv $cardlistfile] { set keyword {card=} }
  if [file exists $cardlistfile] {
    set fid [open $cardlistfile r]
    while {[gets $fid line] >= 0} {
      if [regexp -nocase "$keyword\(\[0-9\]+\)\[^0-9A-Z\]+\(.*\)" $line dummy num cardname] {
	lappend cardlist "$num $cardname"
      }
    }
    close $fid
  }
    return $cardlist
}

proc tuner_list { cardlistfile } {
    set cardlist {}
  if [file exists $cardlistfile] {
    set fid [open $cardlistfile r]
    while {[gets $fid line] >= 0} {
      if [regexp -nocase {tuner=([0-9]+)[^0-9A-Z]+(.*)} $line dummy num cardname] {
	lappend cardlist "$num $cardname"
      }
    }
    close $fid
  }
    return $cardlist
}

proc tuner_list_from_header { headerfile } {
    set tunerlist {}
  if [file exists $headerfile] {
    set fid [open $headerfile r]
    while {[gets $fid line] >= 0} {
      if [regexp {#define  *TUNER_([0-9A-Za-z_]+)[ \t]*([0-9]+)} $line dummy tunername num] {
	set tunerlist [lappend tunerlist "$num $tunername"]
      }
    }
    close $fid
  }
    return $tunerlist
}

proc driver_options { drivername } {
    global lists driver card tuner
    set option(card) {}
    set option(tuner) {}
    foreach device $lists(device) {
	set dev [lindex [split $device { }] 0]
        if [info exists driver($dev)] {
	 if { "$drivername" == "$driver($dev)" } {
	  foreach i {card tuner} {
	    if [info exists ${i}($dev)] {
		set number [set ${i}($dev)]
		if { "$number" != {} } {
		  if { "$option($i)" == {} } {
		    set option($i) "$i=[set ${i}($dev)]"
		  } else {
		    set option($i) "$option($i),[set ${i}($dev)]"
		  }
		}
	    } 
	  }
	 }
        }
    }
    return "$option(card) $option(tuner)"
}

proc load_driver {} {
    global mwn
    global lists entries nums
    global logfile
    global all_drivers
    if [exec id -u] {
	error [m {Only root user can do it.}]
	return
    }
      get_nums
      set dev $nums(device)
      set drvs "$nums(driver)"
      if { "$nums(driver)" == "bttv" } { set drvs { bt878 bttv } }
      set cardnum $nums(card)
      set tunernum $nums(tuner)
      status [m {Removing drivers...}]
      set command {killall xawtv &>/dev/null;sleep 1}
      debug {killing xawtv}
      exec sh -c "$command"
  foreach drv [linsert $drvs 0 {tuner}] {
    set retry yes
    while {$retry} {
      set retry no
	set command "/sbin/rmmod $drv 2>&1 || :"
	debug "removing $drv"
	set line [exec sh -c "$command"]
	if [regexp {busy} $line] {
	  log $line
		set msg "[m {Failed in removing drivers}]: $drv
[m {Quit programs using these drivers.}]"
		error $msg
		set retry yes
        }
    }
  }
      set drv "$nums(driver)"
      set cardnum $nums(card)
            set command {/sbin/lsmod}
      set lines [exec sh -c "$command"]
      if [regexp "$drv" $lines] {
	status [m {Failed in removing drivers}]
      } else {
	if {$entries(ntsc)} {
	    set ntsc_option {ntsc=j}
	} else {
	    set ntsc_option {}
	}
	status [m {Loaing drivers...}]
	set command "/sbin/modprobe tuner $ntsc_option"
	log $command
	set code [catch {exec sh -c $command} msg]
	set command "/sbin/modprobe $drv [driver_options $drv]"
	log $command
	set code [catch {exec sh -c $command} msg]
	log $msg
	set command "dmesg |tail -n 20|grep '$drv.*card=' |tail -n 1"
	log [exec sh -c $command] 
	set command "dmesg |tail -n 20|grep 'tuner.*type' |tail -n 1"
	log [exec sh -c $command] 
	set command "dmesg |tail -n 20|grep '$drv.*video' |tail -n 1"
	log [exec sh -c $command] 
	if $code {
	    status [m {Failed in loading drivers}]
	} else {
	    # update device list
	    set lists(device) [device_list]
	    #set idx [lsearch -glob $lists(device) "$dev *"]
	    #if { $idx >= 0 } {
	#	set entries(device) [lindex $lists(device) $idx]
	    #}
	    #
	    status [m {Starting xawtv}]
	    set command "xawtv -c $dev"
	    log $command
	    set fid [open $logfile w]
	    close $fid
	    set pid [exec xawtv -c $dev 2> $logfile &]
	    after 1000
	    set fid [open $logfile]
	    log [read -nonewline $fid]
	    close $fid
	    set command "ps x | grep '^\[^1-9\]*$pid\[^0-9\]'"
	    if [catch {set line [exec sh -c "$command"]} msg] {
	        debug "PID=$pid stopped"
		status [m {xawtv failed}]
	    } else {
	    	status {}
	        debug "PID=$pid is running"
	    }
	    if [file isfile $logfile] {file delete -force -- $logfile}
	}
      }
}

proc char_minor { device } {
    set major 81
    set minor 0
    set dev [lindex [split $device { }] 0]
	catch {set dev [file readlink $dev]}
	if { [file pathtype $dev] == "relative" } {
	    set dev [file join /dev [file tail $dev]]
	}
    if { [file isfile $dev] || [file isdirectory $dev] } {
	debug "$device is nomal file or directory"
	return { {} {} }
    }
	set command "ls -l $dev"
	set code [catch {set line [exec sh -c $command]} msg]
	if $code {
		debug $msg
		return { {} {} }
	}
	set i 0
	foreach column $line {
	    incr i
	    #debug $column
	    if { $i == 5 } { regexp {[0-9]*} $column major }
	    if { $i == 6 } { set minor $column }
	}
    return $minor
}

proc read_conf {} {
    global mwn
    global lists entries nums written configfile supported_drivers
    global driver card tuner
    foreach d $lists(device) {
	set dev [lindex [split $d { }] 0]
	foreach i {driver card tuner} {
		set ${i}($dev) {}
	}
    }
    foreach i {device driver card tuner} {
	#set ${i}num {}
	set written($i) {}
    }
    set major 81
    set minor {}
    #set dev [lindex $lists(device) 0]
    #set drv bttv
    set ntsc {}

    if [file exists $configfile] {
	debug "reading $configfile"
	set fid [open $configfile r]
	set old [read -nonewline $fid]
	close $fid
	set confdrivers ""
	set oldlines [split $old \n]
	foreach line $oldlines {
	    if [regexp "^alias  *char-major-$major-(\[0-9\]+) +(\[0-9a-z_\]+)" $line dummy minorhere driverhere ] {
		if {! [string match $driverhere $confdrivers]} {
			set confdrivers "$confdrivers|$driverhere"
		}
		set confdriver($minorhere) $driverhere
		debug "***$line"
	    }
	}
	foreach line $oldlines {
	    set drv {}
	    set cardnum {}
	    set tunernum {}
	    if [regexp "^ *options +(tuner$confdrivers) .*" $line dummy drv] {
		debug "***$line"
		regexp {card=([0-9,]+)} $line dummy cardnum
		regexp {tuner.*type=([0-9]+)} $line dummy tunernum
		regexp {tuner.*(ntsc=j)} $line dummy ntsc
		regexp {tuner=([0-9,]+)} $line dummy tunernum
		set card($drv) [split $cardnum {,}]
		set tuner($drv) [split $tunernum {,}]
	    }
	}
    } else { debug "$configfile not found." }
foreach d {bttv ivtv} {
  if [info exists card($d)] { debug "$d:$card($d):$tuner($d)" }
}
#
#parray confdriver
#proc initial_entry
#    global mwn
#    global lists entries nums written configfile supported_drivers
    # initialize entries
    foreach i {device driver card tuner} {
	set entries($i) {}
    }
    foreach i $lists(device) {
	    set dev [lindex [split $i { }] 0]
	    set oldchar [char_minor $dev]
	    if [info exists confdriver($oldchar)] {
	    	set drv  $confdriver($oldchar)
		set driver($dev) $drv
		set card($dev) [lindex $card($drv) 0]
		set card($drv) [lreplace $card($drv) 0 0 ]
		set tuner($dev) [lindex $tuner($drv) 0]
		set tuner($drv) [lreplace $tuner($drv) 0 0 ]
	    	debug "$dev:$drv:$card($dev):$tuner($dev)"
	    }
    }
    if { $ntsc != {} } {
	set entries(ntsc) 1
	debug "tuner ntsc=j"
    } else {
	set entries(ntsc) 0
    }
}

# initialize entries
proc initial_entry {} {
    global mwn
    global lists entries nums written configfile supported_drivers
    global driver card tuner

    # initial message
    help {opening}
    help_append [lookup_pci]

    if { [llength $lists(device)] == 0} {
    	help_append [m {No video device file found.}]
	set lists(device) {/dev/video0}
    }
    set dev [lindex $lists(device) 0]
    recall_entries $dev

    # initialize nums
    get_nums

}

proc recall_entries { device } {
    global lists entries
    global driver card tuner

    set dev [lindex [split $device { }] 0]
    set entries(device) $dev
    foreach i {driver card tuner} {
	if [info exists ${i}($dev)] {
		set entries($i) [set ${i}($dev)]
	}
    }
}


proc write_conf {} {
    global mwn f progname
    global nums written configfile entries
    global lists driver card tuner
    global progname version
    set major 81
    set minor {}
    if { ! [modified] } {
	status [m {configuration already sync}]
	return
    }
    set configdir [file dirname $configfile]
    if { "$configdir" == {} } { set configdir {.} }
    if { [file exists $configfile] && ! [file writable $configfile] || \
	! [file exists $configfile] && ! [file writable $configdir] } { 
    	if [exec id -u] {
		error [m {Only root user can do it.}]
		return
	} else {
		error "$configfile [m {cannot writable}]"
		return
	}
    }
    if {[warn "[m {Modifying}] $configfile\n[m {for next bootup.}]
[m {Continue?}]"] != "yes" } return
	get_nums
      set dev $nums(device)
      set drv $nums(driver)
      set cardnum $nums(card)
      set tunernum $nums(tuner)
    set newdrivers {}
    foreach d $lists(device) {
	set dev [lindex [split $d { }] 0]
	set minor [char_minor $dev]
	if { "$minor" == {} } {
	    error "Device '$dev' is not propper"
	    return
	}
	set drv {}
	if [info exists driver($dev)] {
	    set drv $driver($dev)
	}
debug "$dev:$drv"
	if { "$drv" != {} && "drv" != {none} } {
	  if { [lsearch -exact $newdrivers $drv] < 0 } {
	    set command {/sbin/modprobe -l}
	    set lines [exec sh -c $command]
    	    if [regexp "/$drv\\.k*o" $lines] {
		debug "$drv found"
		lappend newdrivers $drv
	    } else {
 		error "Driver $drv is not propper"
		return
	    }
	  }
    	}
    }
    debug "newdrivers are '$newdrivers'"
    set olddrivers $newdrivers
    lappend olddrivers {tuner}
    debug "olddrivers are '$olddrivers'"
    # read old configfile
    set old {}
    if [file exists $configfile] {
	debug "reading $configfile"
	set fid [open $configfile r]
	set old [read -nonewline $fid]
	close $fid
    }
    # copy to new file
    set fid [open $configfile.new w]
    if { "$old" != {} } {
	set oldlines [split $old \n]
	foreach line $oldlines {
	    set skip 0
	    if [regexp "^\[^#\]*alias  *char-major-$major" $line] {
		set skip 1
	    } elseif [regexp "^\[^#\]*options " $line] {
		foreach drv $olddrivers {
		  if  [regexp "options  *$drv " $line] {
			set skip 1
		  } 
		}
	    } elseif [regexp "### .* $progname" $line] {
			set skip 1
	    }
	    if $skip {
		debug "***$line"
	    } else {
		puts $fid $line
	    }
	}
    }
    # add new entry
    puts $fid "### added by $progname-$version"
    # aliases
    debug "alias char-major-$major videodev"
    puts $fid "alias char-major-$major videodev"
    foreach d $lists(device) {
	set dev [lindex [split $d { }] 0]
	set minor [char_minor $dev]
	if { "$minor" != {} && [info exists driver($dev)] } {
	    set drv $driver($dev)
 	    if { "$drv" != {} && "$drv" != {none} } {
		debug "alias char-major-$major-$minor $drv"
		puts $fid "alias char-major-$major-$minor $drv"
	    }
	}
    }
    # options
    foreach drv $newdrivers {
	set options [driver_options $drv]
        if { "$options" != {} } {
		debug "options $drv $options"
		puts $fid "options $drv $options"
    	}
    }
    if { $entries(ntsc) } {
		debug "options tuner ntsc=j"
		puts $fid "options tuner ntsc=j"
    }
    puts $fid "### end of $progname staff"

    # replace old by new file
	close $fid
	if [file exists $configfile.new] {
	    if [file exists $configfile] {
		file rename -force -- $configfile $configfile.bak
	        status "Backup is $configfile.bak"	  
	    }
	    file rename -force -- $configfile.new $configfile
	    #
	    # update modules.dep
    	    if { [exec id -u] == 0 } {
		set command {/sbin/depmod -a}
		exec sh -c $command
	    }
	}
	foreach i {device driver card tuner} {
		set written($i) $nums($i)
	}
    if { [llength $newdrivers] > 1 } {
	set modprobes {}
	foreach drv $newdrivers {
	    set modprobes "${modprobes}/sbin/modprobe $drv [driver_options $drv]\n"
	}
	help multidriver
	help_append $modprobes
    }
}

set help(multidriver) "
[m {Use modprobe other than configuration file}]
[m {because you are using multiple drivers.}]
[m {Do next commands at boot up}]
[m {in /etc/rc.d/rc.local or somewhere.}]
"

proc lookup_pci {} {
  set msg {}
  set keyword {Multimedia video controller}
  set command {/sbin/lspci}
  if [file executable $command] {
    foreach line [split [exec $command] \n] {
	if [regsub $keyword $line {} condensed] {
	    set msg "$msg\n$condensed"
	}
    }
  }
  if { "$msg" != {} } {
    set msg "[m {Next cards found on pci.}]$msg"
  } else {
    set msg [m {No capture cards found on pci.}]
  }
  return $msg
}

proc modified {} {
    global nums written
    set differ 0
    get_nums
    foreach i {device driver card tuner} {
	if { "$written($i)" != "$nums($i)" } { set differ 1 }
    }
    return $differ
}

set lists(device) [device_list]
set lists(driver) [driver_list]
set lists(card_none) {}
foreach i $all_drivers {
    set cardlist_$i  [file join $cardlistdir "CARDLIST.$i"]
    set lists(card_$i) [card_list [set cardlist_$i]]
}
set cardlist_tuner  [file join $cardlistdir "CARDLIST.tuner"]
set lists(tuner) [tuner_list $cardlist_tuner]
read_conf
debug "bttv [driver_options {bttv}]"
main_window {}

#END
