Browse Source

Finally got EVIOCGBIT ioctl to work correctly. A correctly sized /array/ was needed, not a slice.

Beoran 4 years ago
parent
commit
0eb4d8de35
3 changed files with 116 additions and 14 deletions
  1. 49 1
      os/linux/event_to_string_linux.go
  2. 51 13
      os/linux/input/input_linux.go
  3. 16 0
      os/linux/input/input_linux_test.go

+ 49 - 1
os/linux/event_to_string_linux.go

@@ -23,6 +23,54 @@ func EventTypeToString(e uint) string {
     }
 }
 
-
+func AbsToString(e uint) string {
+    switch e {
+        case ABS_X:              return "ABS_X" 
+        case ABS_Y:              return "ABS_Y" 
+        case ABS_Z:              return "ABS_Z" 
+        case ABS_RX:             return "ABS_RX" 
+        case ABS_RY:             return "ABS_RY" 
+        case ABS_RZ:             return "ABS_RZ" 
+        case ABS_THROTTLE:       return "ABS_THROTTLE" 
+        case ABS_RUDDER:         return "ABS_RUDDER" 
+        case ABS_WHEEL:          return "ABS_WHEEL" 
+        case ABS_GAS:            return "ABS_GAS" 
+        case ABS_BRAKE:          return "ABS_BRAKE" 
+        case ABS_HAT0X:          return "ABS_HAT0X" 
+        case ABS_HAT0Y:          return "ABS_HAT0Y" 
+        case ABS_HAT1X:          return "ABS_HAT1X" 
+        case ABS_HAT1Y:          return "ABS_HAT1Y" 
+        case ABS_HAT2X:          return "ABS_HAT2X" 
+        case ABS_HAT2Y:          return "ABS_HAT2Y" 
+        case ABS_HAT3X:          return "ABS_HAT3X" 
+        case ABS_HAT3Y:          return "ABS_HAT3Y" 
+        case ABS_PRESSURE:       return "ABS_PRESSURE" 
+        case ABS_DISTANCE:       return "ABS_DISTANCE" 
+        case ABS_TILT_X:         return "ABS_TILT_X" 
+        case ABS_TILT_Y:         return "ABS_TILT_Y" 
+        case ABS_TOOL_WIDTH:     return "ABS_TOOL_WIDTH"
+        case ABS_VOLUME:         return "ABS_VOLUME" 
+        case ABS_MISC:           return "ABS_MISC" 
+        case ABS_MT_SLOT:        return "ABS_MT_SLOT"
+        case ABS_MT_TOUCH_MAJOR: return "ABS_MT_TOUCH_MAJOR" 
+        case ABS_MT_TOUCH_MINOR: return "ABS_MT_TOUCH_MINOR" 
+        case ABS_MT_WIDTH_MAJOR: return "ABS_MT_WIDTH_MAJOR" 
+        case ABS_MT_WIDTH_MINOR: return "ABS_MT_WIDTH_MINOR" 
+        case ABS_MT_ORIENTATION: return "ABS_MT_ORIENTATION" 
+        case ABS_MT_POSITION_X:  return "ABS_MT_POSITION_X" 
+        case ABS_MT_POSITION_Y:  return "ABS_MT_POSITION_Y" 
+        case ABS_MT_TOOL_TYPE:   return "ABS_MT_TOOL_TYPE" 
+        case ABS_MT_BLOB_ID:     return "ABS_MT_BLOB_ID"  
+        case ABS_MT_TRACKING_ID: return "ABS_MT_TRACKING_ID" 
+        case ABS_MT_PRESSURE:    return "ABS_MT_PRESSURE" 
+        case ABS_MT_DISTANCE:    return "ABS_MT_DISTANCE" 
+        case ABS_MT_TOOL_X:      return "ABS_MT_TOOL_X" 
+        case ABS_MT_TOOL_Y:      return "ABS_MT_TOOL_Y" 
+        case ABS_MAX:            return "ABS_MAX" 
+        case ABS_CNT:            return "ABS_CNT" 
+        default: return fmt.Sprintf("Unknown absolute axis %d", e)
+    
+    }
+}
  
 

+ 51 - 13
os/linux/input/input_linux.go

@@ -81,24 +81,21 @@ func BitsToLong(bits uint) uint {
     return ((bits) + (8 * SIZEOF_LONG) - 1) / (8 * SIZEOF_LONG)
 }
 
-func TestBit(bit uint, array []linux.UnsignedLong) bool {
-    elem := array[ bit / ( 8 * SIZEOF_LONG)]
-    flag := linux.UnsignedLong(1) << linux.UnsignedLong(bit % (8 * SIZEOF_LONG))
-    return (elem & flag ) != 0
-}
-
 func (d * Device) Topology() (string, error) {
     buffer := [256]byte{}
     err := d.Ioctl(linux.EVIOCGPHYS(uintptr(len(buffer))), unsafe.Pointer(&buffer))
     return string(buffer[0:len(buffer)]), err
 }
 
+func TestBit(array []uint8, bit uint) bool {
+    elem := uint(array[ bit / 8 ])
+    flag := uint(1) << uint(bit % 8)
+    return (elem & flag ) != 0
+}
+
 func (d * Device) SupportedEvents() ([]uint, error) {
-	size := BitsToLong(linux.EV_MAX)
-    bits := make([]linux.UnsignedLong, size)
-    for i := uint(0); i < size; i ++ {
-        bits[i] = 0
-    }
+    var bits [linux.EV_MAX / 8 + 1]uint8
+    size := unsafe.Sizeof(bits)
 	err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
     if err != nil {
         return nil, err
@@ -106,13 +103,54 @@ func (d * Device) SupportedEvents() ([]uint, error) {
     fmt.Printf("size %d, bits: %v\n", size, bits)
     result := []uint{}
     for i := uint(0); i < uint(linux.EV_MAX); i++ {
-        if (TestBit(i, bits)) {
+        if (TestBit(bits[0:len(bits)],i)) {
             result = append(result, uint(i))
 		}
     }
     
     return result, nil
-} 
+}
+
+type InputAbsinfo struct {
+    Value int32
+    Minimum int32
+    Maximum int32
+    Fuzz int32
+    Flat int32
+}
+
+type AbsoluteAxis struct {
+    Index uint
+    InputAbsinfo    
+}
+
+func (d * Device) SupportedAxes() (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
+    }
+    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
+            }
+            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);
+        }
+    }
+    return nil
+}
+
 
 /*    
 	printf("Supported events:\n");

+ 16 - 0
os/linux/input/input_linux_test.go

@@ -95,4 +95,20 @@ func TestSupportedEvents(t * testing.T) {
 		
 }
 
+func TestSupportedAxes(t * testing.T) {
+    device , err := Open(IN)
+    if err != nil {
+        t.Errorf("Error Open: %s\n", err)
+        return
+    }
+    defer device.Close()
+    err = device.SupportedAxes()
+
+/*	t.Logf("Supported events:\n")
+	for i, ev := range events {
+        evname := linux.EventTypeToString(ev)
+        t.Logf("Supported: %d: %d %s", i, int(ev), evname)
+    }
+*/		
+}