|
@@ -5,7 +5,7 @@ package input
|
|
|
import "gitlab.com/beoran/galago/os/linux"
|
|
|
import "os"
|
|
|
import "unsafe"
|
|
|
-import "syscall"
|
|
|
+import syscall "golang.org/x/sys/unix"
|
|
|
import "fmt"
|
|
|
import "path/filepath"
|
|
|
|
|
@@ -34,7 +34,7 @@ func List() ([]string, error) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-// Icotl performs an ioctl on the given de
|
|
|
+// Icotl performs an ioctl on the given device
|
|
|
func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
|
|
|
fmt.Printf("ioctl: %d %d %d\n", uintptr(d.Fd()), uintptr(code), uintptr(pointer))
|
|
|
_, _, errno := syscall.Syscall(
|
|
@@ -93,7 +93,18 @@ func TestBit(array []uint8, bit uint) bool {
|
|
|
return (elem & flag ) != 0
|
|
|
}
|
|
|
|
|
|
-func (d * Device) SupportedEvents() ([]uint, error) {
|
|
|
+type SupportedEvent uint
|
|
|
+
|
|
|
+func (se SupportedEvent) Name() string {
|
|
|
+ return linux.EvToString(uint(se))
|
|
|
+}
|
|
|
+
|
|
|
+func (se SupportedEvent) String() string {
|
|
|
+ return se.Name()
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
|
|
|
var bits [linux.EV_MAX / 8 + 1]uint8
|
|
|
size := unsafe.Sizeof(bits)
|
|
|
err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
|
|
@@ -101,57 +112,105 @@ func (d * Device) SupportedEvents() ([]uint, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
fmt.Printf("size %d, bits: %v\n", size, bits)
|
|
|
- result := []uint{}
|
|
|
+ result := []SupportedEvent{}
|
|
|
for i := uint(0); i < uint(linux.EV_MAX); i++ {
|
|
|
if (TestBit(bits[0:len(bits)],i)) {
|
|
|
- result = append(result, uint(i))
|
|
|
+ result = append(result, SupportedEvent(uint(i)))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return result, nil
|
|
|
}
|
|
|
|
|
|
-type InputAbsinfo struct {
|
|
|
- Value int32
|
|
|
- Minimum int32
|
|
|
- Maximum int32
|
|
|
- Fuzz int32
|
|
|
- Flat int32
|
|
|
-}
|
|
|
+// More Go-like names for the low leve kernel api structs
|
|
|
+
|
|
|
+
|
|
|
+type InputAbsinfo linux.INPUT_absinfo
|
|
|
+type InputEvent linux.INPUT_event
|
|
|
+
|
|
|
|
|
|
type AbsoluteAxis struct {
|
|
|
Index uint
|
|
|
- InputAbsinfo
|
|
|
+ InputAbsinfo
|
|
|
+}
|
|
|
+
|
|
|
+func (ax AbsoluteAxis) Name() string {
|
|
|
+ return linux.AbsToString(ax.Index)
|
|
|
+}
|
|
|
+
|
|
|
+func (ax AbsoluteAxis) String() string {
|
|
|
+ return fmt.Sprintf("%s %d (min:%d max:%d flat:%d fuzz:%d)",
|
|
|
+ ax.Name(),
|
|
|
+ ax.Value,
|
|
|
+ ax.Minimum,
|
|
|
+ ax.Maximum,
|
|
|
+ ax.Flat,
|
|
|
+ ax.Fuzz)
|
|
|
+}
|
|
|
+
|
|
|
+func (ev InputEvent) String() string {
|
|
|
+ return fmt.Sprintf("Event: Time: %d Type: %s, Code: %d, Value:%d",
|
|
|
+ ev.Time,
|
|
|
+ linux.EvToString(uint(ev.Type)),
|
|
|
+ ev.Code,
|
|
|
+ ev.Value)
|
|
|
}
|
|
|
|
|
|
-func (d * Device) SupportedAxes() (error) {
|
|
|
+
|
|
|
+// Read performs a read syscall on the given device
|
|
|
+func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
|
|
|
+ fmt.Printf("read: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
|
|
|
+ read, _, errno := syscall.Syscall(
|
|
|
+ syscall.SYS_READ,
|
|
|
+ uintptr(d.Fd()),
|
|
|
+ uintptr(pointer),
|
|
|
+ uintptr(size))
|
|
|
+ if (errno != 0) {
|
|
|
+ return read, errno
|
|
|
+ }
|
|
|
+ return read, nil
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const READ_EVENTS_MAX = 64
|
|
|
+
|
|
|
+func (d * Device) ReadEvents() ([]InputEvent, error) {
|
|
|
+ var events [READ_EVENTS_MAX]InputEvent
|
|
|
+ size := unsafe.Sizeof(events)
|
|
|
+ read, err := d.Read(unsafe.Pointer(&events), size)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ len := read / unsafe.Sizeof(events[0])
|
|
|
+ return events[0:len], nil
|
|
|
+}
|
|
|
+
|
|
|
+func (d * Device) SupportedAxes() ([]AbsoluteAxis, error) {
|
|
|
var abs_feat InputAbsinfo;
|
|
|
var abs_b [linux.ABS_MAX/8 + 1]uint8;
|
|
|
size := unsafe.Sizeof(abs_b)
|
|
|
err := d.Ioctl(linux.EVIOCGBIT(linux.EV_ABS, size), unsafe.Pointer(&abs_b))
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return nil, err
|
|
|
}
|
|
|
+ result := []AbsoluteAxis{}
|
|
|
fmt.Printf("Supported Absolute axes:\n");
|
|
|
for yalv := uint(0); yalv < linux.ABS_MAX; yalv++ {
|
|
|
if TestBit(abs_b[0:len(abs_b)], uint(yalv)) {
|
|
|
fmt.Printf(" Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
|
|
|
err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return result, err
|
|
|
}
|
|
|
- fmt.Printf("%d (min:%d max:%d flat:%d fuzz:%d)\n",
|
|
|
- abs_feat.Value,
|
|
|
- abs_feat.Minimum,
|
|
|
- abs_feat.Maximum,
|
|
|
- abs_feat.Flat,
|
|
|
- abs_feat.Fuzz);
|
|
|
+ axis := AbsoluteAxis{Index: yalv, InputAbsinfo: abs_feat}
|
|
|
+ result = append(result, axis)
|
|
|
}
|
|
|
}
|
|
|
- return nil
|
|
|
+ return result, nil
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
/*
|
|
|
printf("Supported events:\n");
|
|
|
for (i = 0; i < EV_MAX; i++)
|