#!/bin/bash
#\
exec wish -f "$0" ${1+"$@"}
#
# wacomcpl-exec -- Wacom Control Panel Utility to Change Configuration Setting.
#
# Author	: Ping Cheng
# Creation date	: 04/05/2003
#
# Based on calibrate 1998-99 Patrick Lecoanet --
#
# This code is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this code; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#

package require LIBWACOMXI

set numScreens 1
set currentScreen 0
set desktopWidth [ winfo screenwidth . ]
set desktopHeight [ winfo screenheight . ]
set screenWidth [ winfo screenwidth . ]
set screenHeight [ winfo screenheight . ]
set screenX_org 0
set screenY_org 0
set swapThresh 100
set size 200
set circle_size 10
set line_size 30

set origin_x [ expr ($desktopWidth/2) - ($desktopWidth/4) ]
set origin_y [ expr ($desktopHeight/2) - ($desktopHeight/4) ]
set windowSize "540x300"

set device ""
set deviceIndex 0
set showHelp 0

proc updateCurrentScreenInfo {} {
    global numScreens currentScreen
    global screenWidth screenHeight screenX_org screenY_org 
    global getScreenInfo

    if { $numScreens != 1 } {
        set screenInfo $getScreenInfo(Screen$currentScreen)
	set screenWidth [ lindex $screenInfo 0 ]
	set screenHeight [ lindex $screenInfo 1 ]
	set screenX_org [ lindex $screenInfo 2 ]
	set screenY_org [ lindex $screenInfo 3 ]
   }
}

proc pad {name geometry} {
    global size circle_size line_size

    set circleox [ expr $size/2-$circle_size/2 ]
    set circleoy $circleox
    set circlecx [ expr $circleox+$circle_size ]
    set circlecy $circlecx
    set vertx [ expr $size/2 ]
    set vertoy [ expr ($size-$line_size)/2 ]
    set vertcy [ expr $vertoy+$line_size ]
    set horizox [ expr ($size-$line_size)/2 ]
    set horizcx [ expr $horizox+$line_size ]
    set horizy [ expr $size/2 ]

    toplevel $name
    wm geometry $name $geometry
    wm overrideredirect $name true
    canvas $name.m -height $size -width $size -bg "#505075"
    $name.m create oval $circleox $circleoy $circlecx $circlecy -outline white
    $name.m create line $vertx $vertoy $vertx $vertcy -fill white
    $name.m create line $horizox $horizy $horizcx $horizy -fill white
    pack $name.m
}

proc updateXinitrc {} {
    global device

    exec xsetwacom set $device FileOption

    if { ![ file exists ~/.xinitrc ] } {
	file copy -force /etc/X11/wcm.$device /tmp/wacom
	exec echo "# run the primary system script" >> /tmp/wacom
	exec echo ". /etc/X11/xinit/xinitrc" >> /tmp/wacom
    } else {
	file copy -force ~/.xinitrc ~/.xinitrc.bak
	file copy -force ~/.xinitrc /tmp/xinitrc1
	file copy -force /etc/X11/wcm.$device /tmp/xinitrc
	exec sed -e "/xsetwacom set $device /d" /tmp/xinitrc1 > /tmp/wacom
	exec cat /tmp/wacom >> /tmp/xinitrc
	file copy -force /tmp/xinitrc /tmp/wacom
	file delete -force /tmp/xinitrc /tmp/xinitrc1
    }
    exec sed -e "/default /d" /tmp/wacom > ~/.xinitrc
    file delete -force /tmp/wacom
}

proc calibrationSequence {which xDev yDev} {
    global device calibResults screenY_org screenX_org
    global workingTags screenTags size numScreens
    global swapThresh screenWidth screenHeight
    global getDeviceModel

    set calibResults(xDev,$which) $xDev
    set calibResults(yDev,$which) $yDev
    if { $which == 0 } {
	.topleft.m configure -background "#505075"
	wacomxi::bindevent .topleft.m $device <ButtonRelease> ""
	.bottomright.m configure -background "#df94df"
	wacomxi::bindevent .bottomright.m $device <ButtonRelease> \
		{calibrationSequence 1 %0 %1}
    } elseif { $which == 1 } {
	.bottomright.m configure -background "#505075"
	wacomxi::bindevent .bottomright.m $device <ButtonRelease> ""	
	set borderOffset [expr ($size / 2 )]
	set widthDev [expr $calibResults(xDev,1) - $calibResults(xDev,0)]
 	set heightDev [expr $calibResults(yDev,1) - $calibResults(yDev,0)]
 	set widthX [expr $screenWidth - (2 * $borderOffset)]
 	set heightX [expr $screenHeight - (2 * $borderOffset)]

	#
	# A rough verification of the click
	set clickCheck 0
	if { $calibResults(xDev,1) < $calibResults(xDev,0) } {
	    set clickCheck 1
	}
	if { $calibResults(yDev,1) < $calibResults(yDev,0) } {
	    set clickCheck 1
	}

	if { $clickCheck == 1 } {
	    messageWindow "Warning !!!" \
		"\n\nYou need to click on the center\n\
		of the pink crosshair. Please try again"
	} else {
	    set xDevMin [expr $calibResults(xDev,0) - \
		    ($borderOffset * $widthDev / $widthX)]
	    set xDevMax [expr $calibResults(xDev,1) + \
		    ($borderOffset * $widthDev / $widthX)]
	    set yDevMin [expr $calibResults(yDev,0) - \
		    ($borderOffset * $heightDev / $heightX)]
	    set yDevMax [expr $calibResults(yDev,1) + \
		    ($borderOffset * $heightDev / $heightX)]
	
	    exec xsetwacom set $device topx $xDevMin
	    exec xsetwacom set $device topy $yDevMin
	    exec xsetwacom set $device bottomx $xDevMax
	    exec xsetwacom set $device bottomy $yDevMax
	    # send the same data to the associated eraser
	    set eraser $getDeviceModel($device,eraser)
	    if { [ string compare $eraser $device ] } {
		exec xsetwacom set $eraser topx $xDevMin
		exec xsetwacom set $eraser topy $yDevMin
		exec xsetwacom set $eraser bottomx $xDevMax
		exec xsetwacom set $eraser bottomy $yDevMax
	    }
	    updateXinitrc
	}

	exec xsetwacom set $device gimp on
	destroy .topleft .bottomright
	if { $numScreens > 1 } {
	    .screen.list.label configure -text ""
 	    bindtags .screen.list.list $screenTags
	} else {
	    closeTabWindow
	}
    }
}

proc Calibration {} {
    global numScreens device screenTags

    bindtags .workingDev.list .
    if { $numScreens > 1 } {
	set screenTags [ bindtags .screen.list.list]
    }

    if { $numScreens > 1 } {
	.screen.list.title configure -text "Select $device associated Screen:"
	wm state .screen normal
	disableButtons
    } else {
	updateCurrentScreenInfo
	startCalibration
	disableButtons
    }
}

proc startCalibration {} {
    global device calibResults
    global screenX_org screenY_org size numScreens
    global screenWidth screenHeight
    
    if { $numScreens > 1 } {
	bindtags .screen.list.list .
    }

    set y_coor [ expr $screenY_org+$screenHeight-$size ]
    set x_coor [ expr $screenX_org+$screenWidth-$size ]
    pad .topleft +$screenX_org+$screenY_org
    pad .bottomright +$x_coor+$y_coor
    update
    #
    # Start calib sequence
    catch {unset calibResults}
    exec xsetwacom set $device xydefault
    exec xsetwacom set $device gimp off
    .topleft.m configure -background "#df94df"
    wacomxi::bindevent .topleft.m $device <ButtonRelease> \
		{calibrationSequence 0 %0 %1}
    helpWindow "Help Window " \
		"\n\nPlease click on the center of \n\
		the pink crosshair using $device \n\
		Please don't click on anything else \n\
		by $device before you finish"
}

proc helpWindow { tString mString } {
    global showHelp

    if { $showHelp }  {
	messageWindow $tString $mString
    }
}

proc messageWindow { tString mString } {
    toplevel .mWindow
    wm title .mWindow $tString
    wm transient .mWindow .
    text .mWindow.text -background gray -width 40 -height 10
    button .mWindow.dismiss -text "Dismiss" \
		-command "destroy .mWindow; set ok 1"
    .mWindow.text insert end $mString
    pack .mWindow.text .mWindow.dismiss
    #
    # Do some spiffy animation to draw attention !
    for { set i 0 } { $i < 10 } { incr i } {
	after 100
	.mWindow.text configure -background white
	update
	after 100
	.mWindow.text configure -background gray
	update
    }
    tkwait variable ok 
}

proc updateScreenList {} {
    global currentScreen numScreens screenWidth screenHeight
    global screenX_org screenY_org origin_x origin_y

    if { $numScreens > 1 } {
	set cScreen [ .screen.list.list get anchor ]
	for { set i 0 } { $i < $numScreens } { incr i 1 } {
	    if { $cScreen == "Screen$i" } {
		set currentScreen $i
		set i $numScreens
	    }
	}
    }
    updateCurrentScreenInfo
    set origin_x [ expr $screenX_org+$screenWidth/2-$screenWidth/4 ]
    set origin_y [ expr $screenY_org+$screenHeight/2-$screenHeight/4 ]
    wm geometry . =+$origin_x+$origin_y
    .screen.list.label configure -text $cScreen
    set o_x [ expr $origin_x+100 ]
    set o_y [ expr $origin_y+20 ]
    wm geometry .screen =+$o_x+$o_y
    startCalibration
}

proc disableButtons {} {
    global bName

    if { $bName(pressure) == 1 } {
	.panel.pressure configure -state disabled
    }
    if { $bName(calibrate) == 1 } {
	.panel.calibrate configure -state disabled
    }
    if { $bName(button) == 1 } {
	.panel.button configure -state disabled
    }
    if { $bName(mapping) == 1 } {
	.panel.mapping configure -state disabled
    }
}

proc getDeviceOptionProc { dev i } {
    global getOption getOptionDefault Option

    exec xsetwacom set $dev FileOption
    for { set j 1 } { $j < [ expr $i+1 ] } { incr j 1 } {
	exec awk /$Option($j)/ /etc/X11/wcm.$dev > /tmp/wacom
	exec awk /$dev/ /tmp/wacom > /tmp/wacom1
	exec awk /default/ /tmp/wacom > /tmp/wacom2
	if { [ file exists /tmp/wacom1 ] } {
	    set channelId [open /tmp/wacom1]
	    set info [read -nonewline $channelId]
	    close $channelId
	    set getOption($dev,$Option($j)) [ lrange $info 4 end ]

	}
	if { [ file exists /tmp/wacom2 ] } {
	    set channelId [open /tmp/wacom2]
	    set info [read -nonewline $channelId]
	    close $channelId
	    set getOptionDefault($dev,$Option($j)) [ lindex $info 2 ]
	}
	if { $getOption($dev,$Option($j)) == "" } {
	    set getOption($dev,$Option($j)) $getOptionDefault($dev,$Option($j))
	}
    }
    file delete -force /tmp/wacom /tmp/wacom1 /tmp/wacom2
}


proc updateDevice {} {
    global device deviceIndex getOption
    global numScreens getDeviceModel Option

    if { $device != "" } {
	#
	# Clear old state related to preceding device
	#
	wacomxi::bindevent . $device <ButtonPress> ""
	wacomxi::bindevent . $device <ButtonRelease> ""
#	disableButtons
    }
    
    set device [ .workingDev.list get anchor ]
    set deviceIndex [ .workingDev.list index anchor ]

    if { $device != "" } {
	#
	# Update the entry indicator
	#
	.workingDev.label configure -text $device
	set model $getDeviceModel($device,model)
	set type $getDeviceModel($device,type)
	set Option(1) "Mode"
	getDeviceOptionProc $device 1
	set mode $getOption($device,Mode)
	destroy .panel
	if { ![string compare -nocase -length 6 $model \
		"cintiq"] && [string compare -nocase \
		-length 7 $model "CintiqP" ] || 
		![string compare -nocase -length 5 \
		$model "isdv4"] } {
	    if { ![ string compare $type "stylus" ] } {
	    	if { ![string compare -nocase -length 8 \
		    $mode "absolute"] } {
		    createPanel 1 1 0 1
		}
	    } else {
		createPanel 1 1 0 0
	    }
	} else {
	    if { [ string compare -nocase -length 6 \
		$type "cursor" ] } {
		createPanel 1 1 1 0
	    } else {
		createPanel 0 1 1 0
	    }
	}
    } else {
	#
	# Update the entry indicator
	#
	.workingDev.label configure -text $device
    }
}

proc createDeviceList {infoString} {
    global getDeviceModel

    set index 0
    set devices ""
    set s1 [ lindex $infoString $index ]
    set index [ expr $index+1 ]
    set s2 [ lindex $infoString $index ]
    set index [ expr $index+1 ]
    set s3 [ lindex $infoString $index ]
    set index [ expr $index+1 ]
    set s4 [ lindex $infoString $index ]
    while { $s1 != "" } {
	if { [string compare -length 6 $s1 "Screen" ] } {
	    set getDeviceModel($s1,model) $s2
	    set getDeviceModel($s1,type) $s3
	    set getDeviceModel($s1,eraser) $s4
	    if { [string first $devices $s1] == -1 } {
		set devices "$devices $s1"
	    }
	    set index [expr $index+1]
	    set s1 [ lindex $infoString $index ]
	    set index [ expr $index+1 ]
	    set s2 [ lindex $infoString $index ]
	    set index [ expr $index+1 ]
	    set s3 [ lindex $infoString $index ]
	    set index [ expr $index+1 ]
	    set s4 [ lindex $infoString $index ]
	} else {
	    set s1 ""
	}
    }
    frame .workingDev
    label .workingDev.title -text "Select the Device:"
    label .workingDev.label -background gray
    listbox .workingDev.list -width 16 -height 12 \
	    -yscrollcommand ".workingDev.sb set"
    scrollbar .workingDev.sb -width 10 \
	    -command ".workingDev.list yview"
    grid .workingDev.title -row 0 -column 0 -columnspan 3 -sticky we
    grid .workingDev.label -row 1 -column 0 -columnspan 3 -sticky we
    grid .workingDev.list -row 2 -column 0 
    grid .workingDev.sb -row 2 -sticky nse
    set flag 0
    foreach dev $devices {
	.workingDev.list insert end $dev
    }
    bind .workingDev.list <ButtonRelease-1> updateDevice
}

proc createScreenList {infoString} {
    global numScreens currentScreen
    global desktopHeight desktopWidth getScreenInfo

    set index 0
    set numS 0
    set s0 [ lindex $infoString $index ]
    while { $s0 != "" } {
	if { ![string compare -length 6 $s0 "Screen" ] } {
    	    for { set i 1 } { $i < 5 } { incr i 1 } {
		set index [ expr $index+1 ]
		set s$i [ lindex $infoString $index ]
	    }
	    set getScreenInfo($s0) "$s1 $s2 $s3 $s4"
	    set index [ expr $index+1 ]
	    set s0 [ lindex $infoString $index ]
	    set numS [expr $numS+1]
	} else {
	    set index [ expr $index+4 ]
	    set s0 [ lindex $infoString $index ]
	}
    }
    set numScreens $numS
}

proc screenCancel {} {
    global screenTags

    closeTabWindow
    destroy .topleft .bottomright
    .screen.list.label configure -text ""
    bindtags .screen.list.list $screenTags
    wm state .screen withdraw
}

proc displayScreenList {} {
    global numScreens currentScreen 

    if {  $numScreens <= 1  } {
	return
    }
    toplevel .screen
    wm title .screen "Screen List Window"
    wm transient .screen .
    wm geometry .screen =250x200
    wm state .screen withdraw
    button .screen.cancel -text "Close" -command screenCancel

    frame .screen.list
    label .screen.list.title -text "Select the Screen:"
    label .screen.list.label -background gray
    listbox .screen.list.list -width 12 -height 5 -yscrollcommand ".screen.list.sb set"
    scrollbar .screen.list.sb -width 10 -command ".screen.list yview"
    grid .screen.list.title -row 2 -column 0 -columnspan 3 -sticky we
    grid .screen.list.label -row 3 -column 0 -columnspan 3 -sticky we
    grid .screen.list.list -row 4 -column 0
    grid .screen.list.sb -row 4 -column 1 -sticky nse
    for { set i 0 } { $i < $numScreens } { incr i } {
	.screen.list.list insert end "Screen$i"
    }
    bind .screen.list.list <ButtonRelease-1> updateScreenList
    grid .screen.cancel -row 10
    pack .screen.list .screen.cancel
}

proc updateButton {} {
    global device getDeviceModel sm

    set type $getDeviceModel($device,type)
    set model $getDeviceModel($device,model)
    if { ![string compare -nocase -length 6 $type "cursor"] } {
	set k 6
    }
    if { ![string compare -nocase -length 6 $type "stylus"] } {
	set k 4
    }
    if { ![string compare -nocase -length 6 $type "eraser"] }  {
	set k 2
    }
    for { set i 1 } { $i < $k } { incr i 1 } {
	switch [ .subW.f.$i cget -text ] {
	    "Left"
		{ set j 1 }
	    "Middle"
		{ set j 2 }
	    "Right"
		{ set j 3 }
	    "Fourth"
		{ set j 4 }
	    "Fifth"
		{ set j 5 }
	    "Left Double"
		{ set j 17 }
	    "Mode Toggle"
		{ set j 19 }
	    "Ignore"
		{ set j 18 }
	}
	exec xsetwacom set $device button$i $j 
    }

    if { [string compare -nocase -length 6 $model \
		"cintiq"] || ![string compare -nocase \
		-length 7 $model "CintiqP" ] } { 
	if { [string compare -nocase -length 5 \
		$model "isdv4"] } {
	    set mode [ .subW.f.mode cget -text ]
	    exec xsetwacom set $device mode $mode
	}
    }

    if { ![ string compare -nocase -length 6 $type "stylus" ] } {
	    set smode [ .subW.f.smode cget -text ]
	    if { [string compare -nocase $smode $sm(2)] } {
		exec xsetwacom set $device TPCButton on
	    } else {
		exec xsetwacom set $device TPCButton off
	    }
    }
    updateXinitrc
    closeSubWindow
}

proc initialButton {} {
    global device getDeviceModel sm smode
    global dmode dm getOption Option

    defaultButton
    set type $getDeviceModel($device,type)

    set Option(1) "Mode"
    set Option(2) "TPCButton"
    set Option(3) "Button1"
    set model $getDeviceModel($device,model)
    set t 3
    if { [ string compare -nocase -length 6 $type "eraser" ] } {
	set Option(4) "Button2"
	set Option(5) "Button3"
	set t 5
	if { [ string compare -nocase -length 6 $type "stylus" ] } {
	    set Option(6) "Button4"
	    set Option(7) "Button5"
	    set t 7
	}
    }    
    getDeviceOptionProc $device $t

    if { [string compare -nocase -length 6 $model \
		"cintiq"] || ![string compare -nocase \
		-length 7 $model "CintiqP" ] } {
	if { [string compare -nocase -length 5 \
		$model "isdv4"] } {
	    set dmode $getOption($device,Mode)
	    label .subW.f.modeL -text "Positioning Mode: "
	    tk_optionMenu .subW.f.mode dmode $dm(1) $dm(2)
	    grid .subW.f.mode -row 0 -column 5 -columnspan 15
	    grid .subW.f.modeL -row 0 -column 2
	}
    }

    if { ![ string compare -nocase -length 6 $type "stylus" ] } {
	set smode $getOption($device,TPCButton)
	if { [string compare -nocase -length 3 $smode "off"] } {
	    set smode $sm(1)
	} else {
	    set smode $sm(2)
	}
	label .subW.f.smodeL -text "Side Switch Mode: "
	tk_optionMenu .subW.f.smode smode $sm(1) $sm(2)
	grid .subW.f.smode -row 3 -column 5 -columnspan 15
	grid .subW.f.smodeL -row 3 -column 2
    }

    for { set i 1 } { $i < $t-1 } { incr i 1 } {
	addMenu $i
    }
}

proc displaySubWindow { okF deF initial i} {
    global wName

    toplevel .subW
    wm title .subW "$wName($i)"
    wm transient .subW .
    wm geometry .subW =500x250
    wm state .subW normal
    frame .subW.f
    button .subW.f.ok -text "Ok" -command $okF
    button .subW.f.cancel -text "Cancel" -command closeSubWindow
    button .subW.f.default -text "Default" -command $deF

    disableButtons
    $initial

    grid .subW.f -row 0 -column 0 -sticky nw
    grid .subW.f.ok -row 4 -column 8 -columnspan 3 -padx 10 -pady 10
    grid .subW.f.cancel -row 4 -column 4 -columnspan 3 -padx 10 -pady 10
    grid .subW.f.default -row 4 -column 0 -columnspan 3 -padx 10 -pady 10

    #
    # Suppress tags on listboxes to prevent changing the
    # device and disable other controls
    bindtags .workingDev.list .
}

proc closeSubWindow {} {
    destroy .subW
    closeTabWindow
}

proc closeTabWindow {} {
    global bName workingTags

    if { $bName(pressure) == 1 } {
	.panel.pressure configure -state normal
    }
    if { $bName(calibrate) == 1 } {
	.panel.calibrate configure -state normal
    }
    if { $bName(button) == 1 } {
	.panel.button configure -state normal
    }
    if { $bName(mapping) == 1 } {
	.panel.mapping configure -state normal
    }
    bindtags .workingDev.list $workingTags
}

proc defaultButton {} {
    global db db1 db2 db3 db4 db5 dm sm
    global getDeviceModel dmode device smode

    for { set i 1 } { $i < 6 } { incr i 1 } {
	set db$i $db($i)
    }
    set type $getDeviceModel($device,type)
    if { [ string compare -nocase -length 6 $type "cursor" ] } {
	set dmode $dm(2)
    } else {
	set dmode $dm(1)
    }

    set model $getDeviceModel($device,model)
    if { [string compare -nocase -length 5 $model "isdv4"] } {
	set smode $sm(2)
    } else {
	set smode $sm(1)
    }
}

proc addMenu {t} {
    global db db1 db2 db3 db4 db5
    global getOption device getDeviceModel

    set opt $getOption($device,Button$t)
    if { $opt == "" } { set opt $t }
    set db$t $db($opt) 

    set model $getDeviceModel($device,model)
    if { [string compare -nocase -length 5 $model "isdv4"] } {
	tk_optionMenu .subW.f.$t db$t $db(1) $db(2) $db(3) $db(4) $db(5) $db(17) $db(19) $db(18)
    } else {
	tk_optionMenu .subW.f.$t db$t $db(1) $db(2) $db(3) $db(4) $db(5) $db(17) $db(18)
    }

    label .subW.f.name$t -text "Button $t: "
    if { $t < 3 } {
	set t1 $t
	set t2 1
    } else {
	if { $t < 5 } {
	    set t1 [expr $t-2]
	    set t2 2
	} else {
	    set t1 [expr $t-4]
	    set t2 3
	}
    }

    grid .subW.f.$t -row $t2 -column [expr ($t1-1)*6+3] -columnspan 3 -padx 3 -pady 3
    grid .subW.f.name$t -row $t2 -column [expr ($t1-1)*6] -columnspan 3 -padx 3 -pady 3
}

proc initialT {} {
    global device getDeviceModel
    global getOption getOptionDefault Option

    set Option(1) "TopX"
    set Option(2) "TopY"
    set Option(3) "BottomX"
    set Option(4) "BottomY"
    set Option(5) "SpeedLevel"
    set Option(6) "Accel"
    set Option(7) "Mode"

    getDeviceOptionProc $device 7

    set mode $getOption($device,Mode)
    frame .subW.f.group -bd 10 -bg beige -width 150 -height 150

    if { [ string compare $mode "Relative" ] } {
	label .subW.f.groupL -text "Mapping: "
	for { set i 1 } { $i < 5 } { incr i 1 } {
	    addMapScale $i
	}
    } else {
	label .subW.f.groupL -text "Movement: "
	label .subW.f.group.l1 -text "SpeedLevel: "
	grid .subW.f.group.l1 -row 0 -column 6
	scale .subW.f.group.scale1 -orient horizontal -length 100 \
		-from 1 -to 11
	grid .subW.f.group.scale1 -row 0 -column 8
	.subW.f.group.scale1 set $getOption($device,SpeedLevel)
	label .subW.f.group.l2 -text "Slow"
	grid .subW.f.group.l2 -row 1 -column 7
	label .subW.f.group.l3 -text "Fast"
	grid .subW.f.group.l3 -row 1 -column 9
	label .subW.f.group.l4 -text "Acceleration: "
	grid .subW.f.group.l4 -row 2 -column 6
	scale .subW.f.group.scale2 -orient horizontal -length 100 \
		-from 1 -to 7
	grid .subW.f.group.scale2 -row 2 -column 8
	.subW.f.group.scale2 set $getOption($device,Accel)
	label .subW.f.group.l5 -text "Linear"
	grid .subW.f.group.l5 -row 3 -column 7
	label .subW.f.group.l6 -text "High"
	grid .subW.f.group.l6 -row 3 -column 9
    }

    grid .subW.f.group -row 0 -column 5 
    grid .subW.f.groupL -row 0 -column 2
}

proc addMapScale { t } {
    global getOption Option getOptionDefault device

    label .subW.f.group.l$t -text "$Option($t): "
    grid .subW.f.group.l$t -row [ expr $t-1 ] -column 6
    set j $t
    if { $j < 3 } { set j [expr $j+2] }
    scale .subW.f.group.scale$t -orient horizontal -length 200 \
		-from -200 -to [expr $getOptionDefault($device,$Option($j))+200]
    grid .subW.f.group.scale$t -row [ expr $t-1 ] -column 8
    .subW.f.group.scale$t set $getOption($device,$Option($t))
}

proc updateT {} {
    global getOption getOptionDefault Option device

    set mode $getOption($device,Mode)
    if { ![ string compare $mode "Absolute" ] } {
	for { set i 1 } { $i < 5 } { incr i 1 } {
	    set value [ .subW.f.group.scale$i get ]
	    exec xsetwacom set $device $Option($i) $value
	}
    } else {
	set value [ .subW.f.group.scale1 get ]
	exec xsetwacom set $device SpeedLevel $value
	set value [ .subW.f.group.scale2 get ]
	exec xsetwacom set $device Accel $value
    }
    updateXinitrc
    closeSubWindow
}

proc defaultT {} {
    global getOption getOptionDefault Option device

    set mode $getOption($device,Mode)
    if { ![ string compare $mode "Absolute" ] } {
	for { set i 1 } { $i < 5 } { incr i 1 } {
	    .subW.f.group.scale$i set $getOptionDefault($device,$Option($i))
	}
    } else {
	.subW.f.group.scale1 set $getOptionDefault($device,SpeedLevel)
	.subW.f.group.scale2 set $getOptionDefault($device,Accel)
    }
}

proc initialTip {} {
    global device getDeviceModel getOption Option

    set Option(1) "PressCurve"
    set Option(2) "ClickForce"
    getDeviceOptionProc $device 2

    frame .subW.f.group -bd 10 -bg beige -width 150 -height 150
    label .subW.f.group.groupl1 -text "Sensitivity: "
    grid .subW.f.group.groupl1 -row 0 -column 0
    scale .subW.f.group.scale1 -orient horizontal -length 100 \
		-from 1 -to 7
    grid .subW.f.group.scale1 -row 0 -column 8
    set curve $getOption($device,PressCurve)
    #default curve value
    set value 4

    if { $curve != "" } {
	set p0 [ lindex $curve 0 ]
	set p1 [ lindex $curve 1 ]
	if { $p1 > 5 && $p1 < 35 } {
	    set value 3
	}
	if { $p1 >= 35 && $p1 < 65 } {
	    set value 2
	}
	if { $p1 >= 65 && $p1 < 95 } {
	    set value 1
	}
	if { $p0 > 5 && $p0 < 35 } {
	    set value 5
	}
	if { $p0 >= 35 && $p0 < 65 } {
	    set value 6
	}
	if { $p0 >= 65 && $p0 < 95 } {
	    set value 7
	}
    }
    .subW.f.group.scale1 set $value
    label .subW.f.group.l2 -text "Soft"
    grid .subW.f.group.l2 -row 1 -column 7
    label .subW.f.group.l3 -text "Firm"
    grid .subW.f.group.l3 -row 1 -column 9

    label .subW.f.group.groupl2 -text "Click Force: "
    grid .subW.f.group.groupl2 -row 3 -column 0
    label .subW.f.group.l4 -text "Low"
    grid .subW.f.group.l4 -row 4 -column 7
    label .subW.f.group.l5 -text "High"
    grid .subW.f.group.l5 -row 4 -column 9
    scale .subW.f.group.scale2 -orient horizontal -length 100 \
		-from 1 -to 21
    grid .subW.f.group.scale2 -row 3 -column 8
    .subW.f.group.scale2 set $getOption($device,ClickForce)

    grid .subW.f.group -row 0 -column 5 
}

proc updateTip {} {
    global device 

    switch [ .subW.f.group.scale1 get ] {
	1 
	    { exec xsetwacom set $device PressCurve 0 75 25 100 }
	2  
	    { exec xsetwacom set $device PressCurve 0 50 50 100 }
	3  
	    { exec xsetwacom set $device PressCurve 0 25 75 100 }
	4  
	    { exec xsetwacom set $device PressCurve 0 0 100 100 }
	5  
	    { exec xsetwacom set $device PressCurve 25 0 100 75 }
	6  
	    { exec xsetwacom set $device PressCurve 50 0 100 50 }
	7  
	    { exec xsetwacom set $device PressCurve 75 0 100 25 }
    }
    exec xsetwacom set $device ClickForce [ .subW.f.group.scale2 get ]
    updateXinitrc
    closeSubWindow
}

proc defaultTip {} {
    .subW.f.group.scale1 set 4
    .subW.f.group.scale2 set 6
}

proc createPanel { pressure button mapping calibrate } {
    global bName

    frame .panel
    set bName(pressure) $pressure
    set bName(button) $button
    set bName(mapping) $mapping
    set bName(calibrate) $calibrate
    if { $pressure } {
	button .panel.pressure -text "Feel"\
	    -state normal -command "displaySubWindow \
	    updateTip defaultTip initialTip 1"
	grid .panel.pressure -row 3 -column 0 -columnspan 2 -sticky news -padx 10
    }
    if { $button } {
	button .panel.button -text "Tool Buttons" \
	    -state normal -command "displaySubWindow \
	    updateButton defaultButton initialButton 2"
	grid .panel.button -row 3 -column 3 -columnspan 2 -sticky news -padx 10
    }
    if { $mapping } {
	button .panel.mapping -text "Tracking" \
	    -state normal -command "displaySubWindow \
	    updateT defaultT initialT 3"
	grid .panel.mapping -row 4 -column 3 -columnspan 2 -sticky news -padx 10
    }
    if { $calibrate } {
	button .panel.calibrate -text "Calibrate" \
	    -command Calibration -state normal
	grid .panel.calibrate -row 4 -column 0 -columnspan 2 -sticky news -padx 10
    }
    grid .panel -row 0 -column 1 -columnspan 8 -sticky news -padx 10 -pady 40
}

proc createControls { } {
    global numScreens currentScreen
    global desktopHeight desktopWidth 
    global workingTags db dm sm wName

    set infoString [exec xsetwacom list]
    set index 0
    set dev [ lindex $infoString $index ]
    set index [ expr $index+1 ]
    set type [ lindex $infoString $index ]
    while { $type != "" } {
	if { ![string compare -nocase -length 6 $type "stylus"] \
		|| ![string compare -nocase -length 6 $type "cursor"] \
		|| ![string compare -nocase -length 6 $type "eraser"] } {
	    set type ""
	} else {
	    set index [ expr $index+1 ]
	    set dev [ lindex $infoString $index ]
	    set index [ expr $index+1 ]
	    set type [ lindex $infoString $index ]
	}
    }
    if { $dev == "" } {
	messageWindow "Warning " "\n\nWe didn't find any Wacom device. \n\
		Please make sure the device's \n\
		type (stylus, eraser, or cursor) \n\
		is embeded into its identifier string"
	return
    }
    exec xsetwacom set $dev FileModel
    set channelId [open /etc/wacom.dat]
    set info [read -nonewline $channelId]
    close $channelId

    createDeviceList $info
    createScreenList $info
    displayScreenList

    set db(1) "Left"
    set db(2) "Middle"
    set db(3) "Right"
    set db(4) "Fourth"
    set db(5) "Fifth"
    set db(17) "Left Double"
    set db(19) "Mode Toggle"
    set db(18) "Ignore"
    set dm(1) "Relative"
    set dm(2) "Absolute"

    set sm(1) "Side Switch + Tip"
    set sm(2) "Side Switch Only"

    set wName(1) "Feel"
    set wName(2) "Tool Buttons"
    set wName(3) "Tracking"

    checkbutton .showHelp -text "Turn Help on" -anchor w \
	    -variable showHelp -state normal

    button .exit -text "Exit" -command "exit 0" -padx 40
    
#    grid .showHelp -row 0 -column 2 -sticky nw -padx 30
    grid .exit -row 20 -column 2 -sticky news -padx 20
    grid .workingDev -row 0 -rowspan 25 -column 0 -sticky news -padx 20

    set workingTags [ bindtags .workingDev.list]

    grid columnconfigure . 1 -weight 1
    grid rowconfigure . 7 -weight 5
}

createControls

wm title . "Wacom Control Panel"
wm geometry . =$windowSize+$origin_x+$origin_y

#
# Local Variables:
# mode: tcl
# End:
#
