Browse Source

WIP device flags.

Beoran 4 years ago
parent
commit
2e551ea4ea
4 changed files with 93 additions and 44 deletions
  1. 38 14
      os/linux/event_codes.go
  2. 39 28
      os/linux/input/input_linux.go
  3. 14 0
      os/linux/input/input_linux_test.go
  4. 2 2
      os/linux/input_linux.go

+ 38 - 14
os/linux/event_codes.go

@@ -22,22 +22,46 @@ const INPUT_PROP_CNT = (INPUT_PROP_MAX + 1)
 /*
  * Event types
  */
-
-const EV_SYN = 0x00
-const EV_KEY = 0x01
-const EV_REL = 0x02
-const EV_ABS = 0x03
-const EV_MSC = 0x04
-const EV_SW = 0x05
-const EV_LED = 0x11
-const EV_SND = 0x12
-const EV_REP = 0x14
-const EV_FF = 0x15
-const EV_PWR = 0x16
-const EV_FF_STATUS = 0x17
-const EV_MAX = 0x1f
+type EventType uint
+
+const EV_SYN = EventType(0x00)
+const EV_KEY = EventType(0x01)
+const EV_REL = EventType(0x02)
+const EV_ABS = EventType(0x03)
+const EV_MSC = EventType(0x04)
+const EV_SW  = EventType(0x05)
+const EV_LED = EventType(0x11)
+const EV_SND = EventType(0x12)
+const EV_REP = EventType(0x14)
+const EV_FF  = EventType(0x15)
+const EV_PWR = EventType(0x16)
+const EV_FF_STATUS = EventType(0x17)
+const EV_MAX = EventType(0x1f)
 const EV_CNT = (EV_MAX+1)
 
+
+func (e EventType) String() string { 
+    switch e {
+        case EV_SYN: return "EV_SYN"
+        case EV_KEY: return "EV_KEY"
+        case EV_REL: return "EV_REL"
+        case EV_ABS: return "EV_ABS"
+        case EV_MSC: return "EV_MSC"
+        case EV_SW : return "EV_SW"
+        case EV_LED: return "EV_LED"
+        case EV_SND: return "EV_SND"
+        case EV_REP: return "EV_REP"
+        case EV_FF : return "EV_FF"
+        case EV_PWR: return "EV_PWR"
+        case EV_FF_STATUS: return "EV_FF_STATUS"
+        case EV_MAX: return "EV_MAX"
+        case EV_CNT: return "EV_CNT"
+        default: return "Unknown event"
+    }
+}
+
+
+
 /*
  * Synchronization events.
  */

+ 39 - 28
os/linux/input/input_linux.go

@@ -62,45 +62,56 @@ func (d * Device) Name() (string, error) {
     return string(buffer[0:len(buffer)]), err
 }
 
-func BitsToLong(bits int) int {
-    var ul linux.UnsignedLong 
-    return ((bits) + 8 * unsafe.Sizeof(ul) - 1) / (8 * unsafe.Sizeof(ul))
-}
-
-func TestBit(bit int, array []uint8) { 
-    
-      
-const BITS_PER_LONG = sizeof(long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define OFF(x)  ((x)%BITS_PER_LONG)
-#define BIT(x)  (1UL<<OFF(x))
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define test_bit(bit, array)	((array[LONG(bit)] >> OFF(bit)) & 1)
-
-
 
 func (d * Device) Id() (linux.INPUT_id, error) {
     var result linux.INPUT_id 
     err := d.Ioctl(linux.EVIOCGID, unsafe.Pointer(&result))
     return result, err
+}
+
+// The Linux developers thought it was a great idea a to use an array of 
+// unsigned longs for the bit flags of input devices. Of course, the length 
+// of an unsigned long is platform dependent which then entails all sorts of
+// gymnastics to extract the bits from the array...
 
+const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))      
+const BITS_PER_LONG = SIZEOF_LONG * 8
 
+func BitsToLong(ebits linux.EventType) uint {
+    bits := uint(ebits)
+    return ((bits) + 8 * SIZEOF_LONG - 1) / (8 * SIZEOF_LONG)
+}
 
-	int fd, rd, i, j, k;
-	struct input_event ev[64];
-	int version;
-	unsigned short id[4];
-	unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
-	char name[256] = "Unknown";
-	int abs[5];
+func TestBit(bit uint, array []linux.UnsignedLong) bool {
+    return ((array[ bit / BITS_PER_LONG ]) & (1 << (bit%BITS_PER_LONG))) != 0
+}
 
+func (d * Device) SupportedEvents() ([]linux.EventType, error) {
+	size := BitsToLong(linux.EV_MAX)
+    bits := make([]linux.UnsignedLong, size)
+    for i := uint(0); i < size; i ++ {
+        bits[i] = 0
+    }
+	err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
+    if err != nil {
+        return nil, err
+    }
+    fmt.Printf("size %d, bits: %v\n", size, bits)
+    result := []linux.EventType{}
+    for i := uint(0); i < uint(linux.EV_MAX); i++ {
+        if (TestBit(i, bits)) {
+            result = append(result, linux.EventType(i))
+		}
+    }
+    
+    return result, nil
+} 
 
-func (d * Device) SupportedEvents() ([]uint32, error) (
-	var bit [linux.EV_MAX] uint64
-	device.Ioctl(fd, EVIOCGBIT(0, EV_MAX), unsafe.Pointer(&bit));
+/*    
 	printf("Supported events:\n");
 	for (i = 0; i < EV_MAX; i++)
-		if (test_bit(i, bit[0])) {
+		if (TestBit(i, bit[0])) {
+            
 		}
 		
 
@@ -138,7 +149,7 @@ func (d * Device) SupportedEvents() ([]uint32, error) (
 
 	}
 }
-
+*/
 
 
 

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

@@ -61,6 +61,20 @@ func TestGetId(t * testing.T) {
         id.Bustype, id.Vendor, id.Product, id.Version)
 }
 
+func TestSupportedEvents(t * testing.T) {
+    device , err := Open(IN)
+    if err != nil {
+        t.Errorf("Error Open: %s\n", err)
+        return
+    }
+    defer device.Close()
+    events, err := device.SupportedEvents()
 
+	t.Logf("Supported events:\n")
+	for i, ev := range events {
+        t.Logf("Supported: %d: %d %s", i, int(ev), ev.String())
+    }
+		
+}
 
 

+ 2 - 2
os/linux/input_linux.go

@@ -172,8 +172,8 @@ func EVIOCGSW(len uintptr) uint32 {
     return IOC(IOC_READ, 'E', 0x1b, len)		/* get all switch states */
 }
 
-func EVIOCGBIT(ev uint32, len uintptr) uint32 {	
-    return IOC(IOC_READ, 'E', 0x20 + (ev), len)	/* get event bits */
+func EVIOCGBIT(ev EventType, len uintptr) uint32 {	
+    return IOC(IOC_READ, 'E', 0x20 + (uint32(ev)), len)	/* get event bits */
 }
 
 func EVIOCGABS(abs uint32) uint32 {