# while we're executing a speed command, to avoid loss of steps during
# quick motions.
-# for rel speedws:
-# $s(stepmap) from creator
-
# Interfaces for concrete controllers:
# speedw-new $w $ctrlr {stepmap}
# speedw-setstate $w disabled|normal controller appears/disappears
lappend speedws $w
set s(ctrlr) $ctrlr
set s(inhibit) 0
- set s(commanding) 0
frame $w -relief groove -border 1
label $w.ctrlr -state disabled -text $s(ctrlr)
set s(inhibit) 2
$w.speed configure -foreground red
}
-proc speedw-uninhibit {w} {
+proc speedw-uninhibit {w max} {
upvar #0 speed/$w s
+ set r $s(inhibit)
+ if {$r>$max} { return -1 }
set s(inhibit) 0
$w.speed configure -foreground white
+ return $r
}
proc speedw-setstate {w disnorm} {
$w.train configure -text $t
$w.speed configure -text {} -textvariable train_commanded($t)
set s(inhibit) 1
+ set s(train) $t
$w.speed configure -foreground white
}
proc speedw-userinput-abs {w speed} {
upvar #0 speed/$w s
if {![string length $s(train)]} return
- set $s(queued) $speed
- speedw-check
+ set s(queued) $speed
+ speedw-check $w
}
proc speedw-check {w} {
unset s(queued)
if {$s(inhibit)} {
if {$newspeed > $gcommanded} return
- speedw-uninhibit $w
+ speedw-uninhibit $w 2
}
set s(commanding) $newspeed
scmd speedw-commanded $s(ctrlr) "speed $s(train) $newspeed" $w
}
proc speedw-commanded-nak {m args} { error "got nak from speed: $m" }
-proc speedw-commanded-ok {m w} { upvar #0 speed/$w s; unset s(commanding) }
+proc speedw-commanded-ok {m w} {
+ upvar #0 speed/$w s
+ unset s(commanding)
+ speedw-check $w
+}
proc speedw-commanded-err {m w} {
upvar #0 speed/$w s
unset s(commanding)
speedw-inhibit $w
+ speedw-check $w
}
proc speedw-userinput-rel {w stepmap} {
} else {
set oldspeed $gcommanded
}
- set newspeed [eval $s(stepmap) [list $oldspeed]]
+ set newspeed [eval $stepmap [list $oldspeed]]
speedw-userinput-abs $w $newspeed
}
proc speedws-stastate-hook {} {
global train_commanded stastate
- switch -exact $stastate {
+ switch -exact -- $stastate {
Run {
set trains [array names train_commanded]
speedws-forall speedw-trains-available $trains
speedws-train-problem $train
}
+#---------- concrete input bindings ----------
+
+proc ib-wheelmouse-stepmap {offset oldspeed} {
+ upvar #0 ib_wheelmouse_stepmap map
+ set ixabove 0
+ foreach entry $map {
+ if {$entry==$oldspeed} { set ixbelow $ixabove; break }
+ if {$entry>$oldspeed} break
+ set ixbelow $ixabove
+ incr ixabove
+ }
+ set ix [expr {($offset>0 ? $ixbelow : $ixabove) + $offset}]
+ if {$ix<0} { return 0 }
+ if {$ix>=[llength $map]} { return [lindex $map end] }
+ return [lindex $map $ix]
+}
+
+proc ib-wheelmouse-EV_REL/REL_WHEEL {w value} {
+ if {$value<0} {
+ if {[speedw-uninhibit $w 2]>0} { incr value 1 }
+ if {!$value} return
+ } else {
+ speedw-uninhibit $w 1
+ }
+ speedw-userinput-rel $w [list ib-wheelmouse-stepmap $value]
+}
+
#---------- input device evdev binding ----------
proc bind-input {bus vendor product version concrete ctrlr} {
if {$newlast < $now} { set newlast $now }
set in(laststart) $newlast
manyset [lindex $target($key) 0] ev sysfs
- set cmdl [list ./evdev-manip --grab --stdin-monitor \
+ set cmdl [list 2>@ stderr ./evdev-manip --grab --stdin-monitor \
--expect-sysfs /sys$sysfs/$ev/dev \
/dev/input/$ev]
catch-for-input-binding $key {
debug "i-b $key running $cmdl"
- set in(chan) [open |$cmdl r]
+ set in(chan) [open |$cmdl r+]
fconfigure $in(chan) -blocking 0 -buffering line
fileevent $in(chan) readable [list catch-for-input-binding $key \
[list readable input-binding $in(chan) $key]]
manyset [split $l] dummy dummy kind code value
set proc ib-$in(concrete)-$kind/$code
if {[catch { info args $proc }]} return
- $proc $value
+ $proc $in(w) $value
}
{report-from *} { }
{synch *} { }
register-event ?stastate {ctxch state} {^(.)stastate (\w+|\-) } {
global ctrain trains stastate
set stastate $state
- if {[string compare ctxch |]} speedws-stastate-hook
+ if {[string compare $ctxch |]} speedws-stastate-hook
}
register-event {} {} {^=connected } {
append event_dispatch_body {
debug "ignored $l"
}
-proc train-event-inputline {sconn l} $event_dispatch_body
+proc train-event-inputline {sconn l} "
+puts stderr \"<<<\$l\"
+$event_dispatch_body
+"
proc register-event {args} { error "too late!" }
proc engage-server {} {