}
proc bind-input-raw {devtype concrete args} {
+ set descriptors [exec ./hidrawconv-$devtype -d]
bind-input-core hidraw:[get-unique $devtype] \
- hidraw [list $devtype] \
+ hidraw [list $devtype $descriptors] \
$concrete $args
}
if {[info exists v(devid)] &&
[info exists v(sysfs)] &&
[info exists v(event)]} {
- lappend target($v(devid)) [list $v(event) $v(sysfs)]
+ lappend target(evdev:$v(devid)) [list $v(event) $v(sysfs)]
}
catch { unset v }
}
foreach binding [input-bindings-list hidraw] {
manyset $binding devkind devid devinfo concrete concargs
switch -exact $devkind hidraw { } default continue
- manyset $devinfo devtype
- set rawmap([hidraw-descriptors/$devtype]) \
- [list $devid $devtype $concrete]
+ manyset $devinfo devtype descriptors
+ set rawmap($descriptors) [list $devid $devtype $concrete]
}
if {[array exists rawmap]} {
set new_hidraws [lsort [glob -nocomplain -directory /dev hidraw*]]
continue
}
set raw(devid) $devid
- set raw(chan) $chan
- fconfigure $chan -buffering none -blocking no \
- -encoding binary -eofchar {} -translation binary
- fileevent $chan readable \
- [list hidraw-readable/$devtype $chan $hidraw $devid]
+ set cmdl [list ./hidrawconv-$devtype -e <@ $chan 2>@ stderr]
+ set evch [open |$cmdl r]
+ set raw(chan) $evch
+ fconfigure $evch -blocking 0 -buffering line
+ fileevent $evch readable \
+ [list catch-for-input-binding hidraw $hidraw \
+ [list readable input-binding-raw $evch $hidraw $devid]]
input-binding-present $devid 1 "hidraw $hidraw"
}
set old_hidraws $new_hidraws
continue
}
lappend cmdl 2>@ stderr
- catch-for-input-binding $devid {
+ catch-for-input-binding evdev $devid {
debug "ib $devid running $cmdl"
set in(chan) [open |$cmdl r+]
fconfigure $in(chan) -blocking 0 -buffering line
- fileevent $in(chan) readable [list catch-for-input-binding $devid \
+ fileevent $in(chan) readable \
+ [list catch-for-input-binding evdev $devid \
[list readable input-binding $in(chan) $devid]]
}
}
proc input-binding-eof {chan devid} {
upvar #0 input/$devid in
- fconfigure $in(chan) -blocking 1
- close $in(chan)
- error "evdev-manip exited" {} {CHILDSTATUS ? 0}
+ input-binding-eof-core $in(chan) "evdev-manip exited"
+}
+
+proc input-binding-eof-core {chan msg} {
+ fconfigure $chan -blocking 1
+ close $chan
+ error $msg {} {CHILDSTATUS ? 0}
+}
+
+proc input-binding-raw-eof {chan hidraw devid} {
+ upvar #0 hidraw/$hidraw raw
+ input-binding-eof-core $raw(chan) "hidrawconv-* exited"
}
proc input-binding-inputline {chan l devid} {
- global showunbound
upvar #0 input/$devid in
- if {![catch { info args ib-inputline/$in(concrete) }]} {
- # give the input binding first dibs
- if {[ib-inputline/$in(concrete) $devid $l]} return
- }
+ if {[input-binding-inputline-core-ib $devid $l]} return
regsub {^[^ ]+ } $l {} lr
switch -glob -- $lr {
{opened *} {
debug "ib $devid start << $l"
- input-binding-present 1 $devid "evdev open"
+ input-binding-present $devid 1 "evdev open"
}
{[-0-9]*} {
manyset [split $lr] value kindl kindr codel coder
- set proc ib-ev/$in(concrete)/${kindl}_${kindr}/${codel}_${coder}
- if {[catch { info args $proc }]} {
- if {$showunbound} {
- debug "ib $devid unbound $proc << $l"
- }
- return
- }
- $proc $devid $value
+ input-binding-inputline-core-ev $devid \
+ ${kindl}_${kindr}/${codel}_${coder} $value $l
}
* {
debug "ib $devid ignored << $l"
}
}
-proc catch-for-input-binding {devid body} {
+proc input-binding-inputline-core-ib {devid l} {
+ # give the input binding first dibs
+ upvar #0 input/$devid in
+ if {[catch { info args ib-inputline/$in(concrete) }]} { return 0 }
+ return [ib-inputline/$in(concrete) $devid $l]
+}
+
+proc input-binding-inputline-core-ev {devid kindcode value l} {
+ global showunbound
upvar #0 input/$devid in
+ set proc ib-ev/$in(concrete)/$kindcode
+ if {[catch { info args $proc }]} {
+ if {$showunbound} {
+ debug "ib $devid unbound $proc << $l"
+ }
+ return
+ }
+ $proc $devid $value
+}
+
+proc input-binding-raw-inputline {chan l hidraw devid} {
+ upvar #0 hidraw/$hidraw raw
+ if {[input-binding-inputline-core-ib $devid $l]} return
+ manyset [split $l] kind code value
+ input-binding-inputline-core-ev $devid $kind/$code $value $l
+}
+
+proc catch-for-input-binding {devkind ident body} {
global errorInfo errorCode
set r [catch { uplevel 1 $body } rv]
if {$r!=1} { return -code $r $rv }
{POSIX *} { set m "communication error: [lindex $errorCode 1]" }
* { error $rv $errorInfo $errorCode }
}
- debug "ib $devid died $m"
+ debug "ib $devkind $ident died $m"
+ input-binding-destroy/$devkind $ident $m
+}
+
+proc input-binding-destroy/evdev {devid m} {
+ upvar #0 input/$devid in
catch { close $in(chan) }
catch { unset in(chan) }
-
input-binding-present $devid 0 "died $m"
}
+proc input-binding-destroy/hidraw {hidraw m} {
+ upvar #0 hidraw/$hidraw raw
+ catch { close $raw(chan) }
+ catch { unset raw(chan) }
+ input-binding-present $raw(devid) 0 "died $m"
+}
+
proc engage-input-bindings {} {
scan-input-bindings
}