New mechanism
This commit is contained in:
69
internal/temper/discovery_linux.go
Normal file
69
internal/temper/discovery_linux.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package temper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Function which scans /dev for temperXX devices (configured by udev)
|
||||
//
|
||||
// A timeout of 250ms is recommended but as YMMV, this function allows
|
||||
// for an arbitrary timeout.
|
||||
func FindTempersWithTimeout(timeout time.Duration) ([]*Temper, error) {
|
||||
// list over dev folder for temperXX devices
|
||||
dirEnts, err := os.ReadDir("/dev")
|
||||
if err != nil {
|
||||
return []*Temper{}, err
|
||||
}
|
||||
|
||||
tempers := []*Temper{}
|
||||
for _, d := range dirEnts {
|
||||
if name := d.Name(); strings.HasPrefix(name, "temper") {
|
||||
if isInputDevice(name) {
|
||||
continue
|
||||
}
|
||||
temper, err := New(filepath.Join("/dev", name))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
// attempt to take a reading from the temper
|
||||
// if the reading times out, assume it's a false positive
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
_, err = temper.ReadCWithContext(ctx)
|
||||
if err == nil {
|
||||
tempers = append(tempers, temper)
|
||||
} else {
|
||||
// prevent file descriptor leaks
|
||||
temper.Close()
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
return tempers, nil
|
||||
}
|
||||
|
||||
// Helper function to return list of temper devices available in /dev
|
||||
//
|
||||
// Uses the recommended default timeout of 250ms. See
|
||||
// FindTempersWithTimeout for more details
|
||||
func FindTempers() ([]*Temper, error) {
|
||||
return FindTempersWithTimeout(time.Millisecond * 250)
|
||||
}
|
||||
|
||||
// Determines if the current hidraw device also doubles as a virtual keyboard
|
||||
//
|
||||
// some temper devices also have a keyboard emulation mode.
|
||||
// The regular discovery function can trigger data entry mode, and cause
|
||||
// annoying and distracting typing to happen, so this function allows us to
|
||||
// skip the check on devices we know aren't temper sensors
|
||||
func isInputDevice(temperDescriptor string) bool {
|
||||
hidrawDesc := strings.ReplaceAll(temperDescriptor, "temper", "hidraw")
|
||||
inputPath := filepath.Join("/sys/class/hidraw", hidrawDesc, "device/input")
|
||||
if _, statErr := os.Stat(inputPath); statErr == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
Reference in New Issue
Block a user