Fix sff panic deadlock, share the evdev probe, assorted review cleanups
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
// Package evdev is the kernel input-event ABI.
|
||||
package evdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
Syn = 0x00
|
||||
Key = 0x01
|
||||
Abs = 0x03
|
||||
SynReport = 0x00
|
||||
BtnTouch = 0x14a
|
||||
AbsX = 0x00
|
||||
AbsY = 0x01
|
||||
|
||||
propDirect = 0x01
|
||||
|
||||
EventSize = 24
|
||||
)
|
||||
|
||||
func ioc(nr, size uintptr) uintptr {
|
||||
const iocRead = 2
|
||||
return iocRead<<30 | size<<16 | 'E'<<8 | nr
|
||||
}
|
||||
|
||||
type Touchscreen struct {
|
||||
F *os.File
|
||||
MinX, MaxX, MinY, MaxY int32
|
||||
}
|
||||
|
||||
// Picks the direct-input device that reports absolute X and Y, which is the
|
||||
// touchscreen; a mouse is relative and a keyboard has no absolute axes.
|
||||
func FindTouchscreen(flag int) (*Touchscreen, error) {
|
||||
paths, err := filepath.Glob("/dev/input/event*")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range paths {
|
||||
f, err := os.OpenFile(p, flag, 0)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var props, absBits uint64
|
||||
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(),
|
||||
ioc(0x09, 8), uintptr(unsafe.Pointer(&props))); errno != 0 {
|
||||
f.Close()
|
||||
continue
|
||||
}
|
||||
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(),
|
||||
ioc(0x20+Abs, 8), uintptr(unsafe.Pointer(&absBits))); errno != 0 {
|
||||
f.Close()
|
||||
continue
|
||||
}
|
||||
if props&(1<<propDirect) == 0 ||
|
||||
absBits&(1<<AbsX) == 0 || absBits&(1<<AbsY) == 0 {
|
||||
f.Close()
|
||||
continue
|
||||
}
|
||||
t := &Touchscreen{F: f}
|
||||
if t.MinX, t.MaxX, err = axisRange(f, AbsX); err != nil {
|
||||
f.Close()
|
||||
return nil, fmt.Errorf("%s x range: %w", p, err)
|
||||
}
|
||||
if t.MinY, t.MaxY, err = axisRange(f, AbsY); err != nil {
|
||||
f.Close()
|
||||
return nil, fmt.Errorf("%s y range: %w", p, err)
|
||||
}
|
||||
if t.MaxX <= t.MinX || t.MaxY <= t.MinY {
|
||||
f.Close()
|
||||
return nil, fmt.Errorf("%s: degenerate axes x %d..%d y %d..%d",
|
||||
p, t.MinX, t.MaxX, t.MinY, t.MaxY)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
return nil, fmt.Errorf("no touchscreen found among /dev/input/event*")
|
||||
}
|
||||
|
||||
func axisRange(f *os.File, axis uintptr) (min, max int32, err error) {
|
||||
var info [6]int32
|
||||
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(),
|
||||
ioc(0x40+axis, 24), uintptr(unsafe.Pointer(&info[0]))); errno != 0 {
|
||||
return 0, 0, errno
|
||||
}
|
||||
return info[1], info[2], nil
|
||||
}
|
||||
Reference in New Issue
Block a user