#!/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 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 400
set circle_size 10
set line_size 30
set config_file "~/.wacomcplrc"

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 device numScreens currentScreen
    global screenWidth screenHeight screenX_org screenY_org 
    global getScreenInfo

    if { $numScreens($device) != 1 } {
        set screenInfo $getScreenInfo($device,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 {device option value} {

    global config_file

    if { ![ file exists $config_file ] } {
    exec echo "xsetwacom set $device $option \"$value\"" > $config_file
    } else {
    file copy -force $config_file $config_file~
    file copy -force $config_file /tmp/wacomcpl.tmp
    exec sed -e "/xsetwacom set $device $option /d" /tmp/wacomcpl.tmp > /tmp/wacomcpl2.tmp
    exec echo "xsetwacom set $device $option \"$value\"" > $config_file
    exec cat /tmp/wacomcpl2.tmp >> $config_file
    file delete -force /tmp/wacomcpl2.tmp /tmp/wacomcpl.tmp
    }
    if { $option == "PressCurve" } {
    set index 0
    set v1 [ lindex $value $index ]
        for { set i 2 } { $i < 5 } { incr i 1 } {
        set index [ expr $index+1 ]
        set v$i [ lindex $value $index ]
    }
    exec xsetwacom set $device $option $v1 $v2 $v3 $v4
    } else {
    exec xsetwacom set $device $option $value
    }
}

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
    set xDevMin $calibResults(xDev,0)
    set xDevMax $calibResults(xDev,1)
    set yDevMin $calibResults(yDev,0)
    set yDevMax $calibResults(yDev,1)
    if { $calibResults(xDev,1) < $calibResults(xDev,0) } {
        set clickCheck 1
        set xDevMin $calibResults(xDev,1)
        set xDevMax $calibResults(xDev,0)
    }
    if { $calibResults(yDev,1) < $calibResults(yDev,0) } {
        set clickCheck 1
        set yDevMin $calibResults(yDev,1)
        set yDevMax $calibResults(yDev,0)
    }

    if { $clickCheck == 1 } {
        messageWindow "Warning !!!" \
        "\n\nThere was something unusual in your calibration step.\n\
        If you are pretty sure that you have clicked on the center\n\
        of the pink crosshair, you are fine. Otherwise, try it again."
    }
    set xDevMin [expr $xDevMin - ($borderOffset * $widthDev / $widthX)]
    set xDevMax [expr $xDevMax + ($borderOffset * $widthDev / $widthX)]
    set yDevMin [expr $yDevMin - ($borderOffset * $heightDev / $heightX)]
    set yDevMax [expr $yDevMax + ($borderOffset * $heightDev / $heightX)]
    
    updateXinitrc $device topx $xDevMin
    updateXinitrc $device topy $yDevMin
    updateXinitrc $device bottomx $xDevMax
    updateXinitrc $device bottomy $yDevMax
    # send the same data to the associated eraser
    set eraser $getDeviceModel($device,eraser)
    if { [ string compare $eraser $device ] } {
        updateXinitrc $eraser topx $xDevMin
        updateXinitrc $eraser topy $yDevMin
        updateXinitrc $eraser bottomx $xDevMax
        updateXinitrc $eraser bottomy $yDevMax
    }

    destroy .topleft .bottomright
    if { $numScreens($device) > 1 } {
        .screen.list.label configure -text ""
         bindtags .screen.list.list $screenTags
    } else {
        closeTabWindow
    }
    }
}

proc Calibration {} {
    global numScreens device screenTags getOption Option

    set Option(1) "Mode"
    getDeviceOptionProc $device 1
    set mode $getOption($device,Mode)
    if { $mode != 1 } {
    disableButtons
    messageWindow "Warning " "\n\nDevice $device is in relative mode. \n\
        You can calibrate $device only when it is in absolute mode. \n\
        Please swith $device's mode and try again. "
    closeTabWindow
    return
    }

    bindtags .workingDev.list .
    if { $numScreens($device) > 1 } {
    displayScreenList $device
    set screenTags [ bindtags .screen.list.list]
    .screen.list.title configure -text "Select $device associated Screen:"
    wm state .screen normal
    } else {
    updateCurrentScreenInfo
    startCalibration
    }
    disableButtons
}

proc startCalibration {} {
    global device calibResults
    global screenX_org screenY_org size numScreens
    global screenWidth screenHeight
    
    if { $numScreens($device) > 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
    .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 device screenX_org screenY_org origin_x origin_y

    if { $numScreens($device) > 1 } {
    set cScreen [ .screen.list.list get anchor ]
    for { set i 0 } { $i < $numScreens($device) } { incr i 1 } {
        if { $cScreen == "Screen$i" } {
        set currentScreen $i
        set i $numScreens($device)
        }
    }
    }
    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 db

    for { set j 1 } { $j < [ expr $i+1 ] } { incr j 1 } {
    set value [ exec xsetwacom get $dev $Option($j) ] 
    set value1 [ exec xsetwacom getdefault $dev $Option($j) ] 
    if { ![ string compare -nocase -length 10 $Option($j) "PressCurve" ] } {
        set getOption($dev,PressCurve) 4
        set getOptionDefault($dev,PressCurve) 4

        set p0 [ expr ( $value >> 24) & 0xFF ]
        set p1 [ expr ( $value >> 16) & 0xFF ]
        if { ($p1 > 5) && ($p1 < 35) } {
        set getOption($dev,PressCurve) 3
        }
        if { ($p1 >= 35) && ($p1 < 65) } {
        set getOption($dev,PressCurve) 2
        }
        if { ($p1 >= 65) && ($p1 < 95) } {
        set getOption($dev,PressCurve) 1
        }
        if { ($p0 > 5) && ($p0 < 35) } {
        set getOption($dev,PressCurve) 5
        }
        if { ($p0 >= 35) && ($p0 < 65) } {
        set getOption($dev,PressCurve) 6
        }
        if { ($p0 >= 65) && ($p0 < 95) } {
        set getOption($dev,PressCurve) 7
        }
    } else {
        if { ![string compare -nocase -length 6 $Option($j) "button"] } {
        if { ($value > 19) || ($value == 0) } {
            set output [ exec xsetwacom get $dev $Option($j) ]
            set outputd [ lindex $output 0 ]
            if { ![string compare -nocase -length 8 DBLCLICK $outputd ] } {
            set getOption($dev,$Option($j)) 17
            }
            if { ![string compare -nocase -length 10 MODETOGGLE $outputd ] } {
            set getOption($dev,$Option($j)) 19
            }
            if { ($value == 0) } {
            set getOption($dev,$Option($j)) 18
            }
        } else {
            set getOption($dev,$Option($j)) $value
        }
        } else {
        set getOption($dev,$Option($j)) $value
        }
        set getOptionDefault($dev,$Option($j)) $value1
    }
    }
}

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

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

    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 { $isLCD($model) } {
        if { ![ string compare $type "stylus" ] } {
        createPanel $device 1 1 0 1
        } else {
        if { [ string compare -nocase -length 6 \
            $type "cursor" ] } {
            createPanel $device 1 1 0 0
        } else {
            createPanel $device 0 0 0 0
        }
        }
    } else {
        if { [ string compare -nocase -length 6 \
        $type "cursor" ] } {
        createPanel $device 1 1 1 0
        } else {
        createPanel $device 0 1 1 0
        }
    }
    } else {
    #
    # Update the entry indicator
    #
    .workingDev.label configure -text $device
    }
}

proc createDeviceList {} {
    global getDeviceModel

    set infoString [exec xsetwacom list]
    set index 0
    set devices ""
    set dev [ lindex $infoString $index ]
    while { $dev != "" } {
    set index [ expr $index+1 ]
    set type [ lindex $infoString $index ]
    set index [ expr $index+1 ]

    if { [string compare $type "pad"] } {
        set getDeviceModel($dev,type) $type
        set getDeviceModel($dev,model) [ exec xsetwacom get $dev TabletID ]
        set devices "$devices $dev"
    }
        set dev [ lindex $infoString $index ]
    }

    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
    createScreenList $dev
    set type $getDeviceModel($dev,type)
    if { ![string compare $type "eraser"] } {
        set model $getDeviceModel($dev,model)
        foreach dev1 $devices {
        set type1 $getDeviceModel($dev1,type)
        set model1 $getDeviceModel($dev1,model)
        if { ( $model == $model1 ) 
            && ![string compare $type1 "stylus"] } {
            set getDeviceModel($dev1,eraser) $dev
        }
        }
    }
    }
    bind .workingDev.list <ButtonRelease-1> updateDevice
}

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

    set numScreens($dev) [ exec xsetwacom get $dev NumScreen ]
    for { set i 0 } {$i < $numScreens($dev)} { incr i 1 } {
    set s1 [ exec xsetwacom get $dev SBottomX$i ]
    set s2 [ exec xsetwacom get $dev SBottomY$i ]
    set s3 [ exec xsetwacom get $dev STopX$i ]
    set s4 [ exec xsetwacom get $dev STopY$i ]
    set getScreenInfo($dev,Screen$i) "$s1 $s2 $s3 $s4"
    }
}

proc screenCancel {} {
    global screenTags

    closeTabWindow
    destroy .topleft .bottomright .screen
}

proc displayScreenList { dev } {
    global numScreens currentScreen 

    if {  $numScreens($dev) <= 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($dev) } { 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 getOption dm isLCD

    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 
          set v "Button 1" }
        "Middle"
        { set j 2 
         set v "Button 2" }
        "Right"
        { set j 3 
         set v "Button 3" }
        "Fourth"
        { set j 4 
         set v "Button 4" }
        "Fifth"
        { set j 5 
         set v "Button 5" }
        "Left Double"
        { set j 17 
         set v "DBLCLICK 1" }
        "Mode Toggle"
        { set j 19 
         set v "ModeToggle 1" }
        "Ignore"
        { set j 18 
         set v "Button 0" }
    }
    set getOption($device,button$i) $j
    updateXinitrc $device button$i $v
    }

    if { !$isLCD($model) && [string compare $type "pad"] } {
    set mode [ .subW.f.mode cget -text ]
    updateXinitrc $device mode $mode
    if { $mode == $dm(1) } {
        set getOption($device,Mode) 0
    } else {
        set getOption($device,Mode) 1
    }
    }

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

proc defaultButton {} {
    global db db1 db2 db3 db4 db5 dm sm dmv smv isLCD
    global device getOptionDefault getDeviceModel

    for { set i 1 } { $i < 6 } { incr i 1 } {
    set db$i $db($i)
    }

    set model $getDeviceModel($device,model)
    set type $getDeviceModel($device,type)

    if { !$isLCD($model) && [ string compare $type "pad" ] } {
    set dmv $dm([ expr $getOptionDefault($device,Mode)+1 ])
    }

    if { ![ string compare -nocase -length 6 $type "stylus" ] } {
    set smv $sm([ expr $getOptionDefault($device,TPCButton)+1 ])
    }
}

proc initialButton {} {
    global device getDeviceModel Option

    set type $getDeviceModel($device,type)

    set Option(1) "Mode"
    set Option(2) "TPCButton"
    set Option(3) "Button1"
    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

    displayMode

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

proc displayMode {} {
    global device getDeviceModel sm smv
    global dmv dm getOption isLCD

    set model $getDeviceModel($device,model)
    set type $getDeviceModel($device,type)

    if { !$isLCD($model) && [ string compare $type "pad" ] } {
     set dmv $dm([ expr $getOption($device,Mode)+1 ])
    tk_optionMenu .subW.f.mode dmv $dm(1) $dm(2)
    label .subW.f.modeL -text "Positioning Mode: "
    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 smv $sm([ expr $getOption($device,TPCButton)+1 ])
    tk_optionMenu .subW.f.smode smv $sm(1) $sm(2)
    label .subW.f.smodeL -text "Side Switch Mode: "
    grid .subW.f.smode -row 3 -column 5 -columnspan 15
    grid .subW.f.smodeL -row 3 -column 2
    }
}

proc displaySubWindow { okF deF initial i d} {
    global wName

    toplevel .subW
    wm title .subW "$d: $wName($i)"
    wm transient .subW .
    wm geometry .subW =650x425
    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 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 {  $model != 144 } { 
    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 { $mode == 1 } {
    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 { $mode == 1 } {
    for { set i 1 } { $i < 5 } { incr i 1 } {
        set value [ .subW.f.group.scale$i get ]
        updateXinitrc $device $Option($i) $value
        set getOption($device,$Option($i)) $value
    }
    } else {
    set value [ .subW.f.group.scale1 get ]
    updateXinitrc $device SpeedLevel $value
    set value [ .subW.f.group.scale2 get ]
    updateXinitrc $device Accel $value
    set getOption($device,Accel) $value
    }
    closeSubWindow
}

proc defaultT {} {
    global getOption getOptionDefault Option device

    set mode $getOption($device,Mode)
    if { $mode == 1 } {
    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"
    set Option(3) "RawSample"
    set Option(4) "Suppress"
    getDeviceOptionProc $device 4

    frame .subW.f.group -bd 10 -bg beige -width 150 -height 150
    label .subW.f.group.groupl1 -text "Tip 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)

    .subW.f.group.scale1 set $curve
    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)

    label .subW.f.group.groupl3 -text "Smoothness: "
    grid .subW.f.group.groupl3 -row 5 -column 0
    label .subW.f.group.l6 -text "Low"
    grid .subW.f.group.l6 -row 6 -column 7
    label .subW.f.group.l7 -text "High"
    grid .subW.f.group.l7 -row 6 -column 9
    scale .subW.f.group.scale3 -orient horizontal -length 100 \
               -from 1 -to 20
    grid .subW.f.group.scale3 -row 5 -column 8
    .subW.f.group.scale3 set $getOption($device,RawSample)

    label .subW.f.group.groupl4 -text "Suppress Points: "
    grid .subW.f.group.groupl4 -row 7 -column 0
    label .subW.f.group.l8 -text "Low"
    grid .subW.f.group.l8 -row 8 -column 7
    label .subW.f.group.l9 -text "High"
    grid .subW.f.group.l9 -row 8 -column 9
    scale .subW.f.group.scale4 -orient horizontal -length 100 \
               -from 1 -to 20
    grid .subW.f.group.scale4 -row 7 -column 8
    .subW.f.group.scale4 set $getOption($device,Suppress)

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

proc updateTip {} {
    global device 

    switch [ .subW.f.group.scale1 get ] {
    1 
        { set curve "0 75 25 100" }
    2  
        { set curve "0 50 50 100" }
    3  
        { set curve "0 25 75 100" }
    4  
        { set curve "0 0 100 100" }
    5  
        { set curve "25 0 100 75" }
    6  
        { set curve "50 0 100 50" }
    7  
        { set curve "75 0 100 25" }
    }
    updateXinitrc $device PressCurve $curve
    set getOption($device,PressCurve) $curve
    updateXinitrc $device ClickForce [ .subW.f.group.scale2 get ]
    set getOption($device,ClickForce) [ .subW.f.group.scale2 get ]
    updateXinitrc $device RawSample [ .subW.f.group.scale3 get ]
    set getOption($device,RawSample) [ .subW.f.group.scale3 get ]
    updateXinitrc $device Suppress [ .subW.f.group.scale4 get ]
    set getOption($device,Suppress) [ .subW.f.group.scale4 get ]
    closeSubWindow
}

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

proc createPanel { device 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 $device"
    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 $device"
    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 $device"
    grid .panel.mapping -row 4 -column 3 -columnspan 2 -sticky news -padx 10
    }
    if { $calibrate } {
    button .panel.calibrate -text "Calibrate ($device)" \
        -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 updateModelInfo { } {
    global isLCD

    for { set i 0 } { $i <= 198 } { incr i 1 } {
    set isLCD($i) 0
    }
    #PL
    for { set i 48} { $i <= 63 } { incr i 1 } {
    set isLCD($i) 1
    }
    #TabletPC
    for { set i 144 } { $i <= 151 } { incr i 1 } {
    set isLCD($i) 1
    }
    #Cintiq
    for { set i 192 } { $i <= 198 } { incr i 1 } {
    set isLCD($i) 1
    }
}

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

    createDeviceList 
    updateModelInfo

    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 Only"
    set sm(2) "Side Switch + Tip"

    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:
#