Browse Source

Use pos.File.SyscallCon for better access to the FD and to enable nonblocking communication.

Beoran 4 years ago
parent
commit
fbb68a17c4
6 changed files with 254 additions and 136 deletions
  1. 5 0
      go.mod
  2. 14 0
      go.sum
  3. 206 122
      os/linux/input/input_linux.go
  4. 27 12
      os/linux/input/input_linux_test.go
  5. 1 1
      os/linux/linux32.go
  6. 1 1
      os/linux/linux64.go

+ 5 - 0
go.mod

@@ -3,6 +3,11 @@ module gitlab.com/beoran/galago
 go 1.12
 
 require (
+	github.com/BurntSushi/xgb v0.0.0
+	github.com/andybalholm/c2go v0.0.0-20190812182517-7b628d7f3263 // indirect
+	github.com/elliotchance/c2go v0.25.9 // indirect
 	github.com/seccomp/libseccomp-golang v0.9.1
 	golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13
 )
+
+replace github.com/BurntSushi/xgb v0.0.0 => ../xgb

+ 14 - 0
go.sum

@@ -1,4 +1,18 @@
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046 h1:O/r2Sj+8QcMF7V5IcmiE2sMFV2q3J47BEirxbXJAdzA=
+github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
+github.com/NeowayLabs/drm v0.0.0-20190824133025-4939fc0ad345 h1:gsz1u5J8hnoPtBaA5dUdluC4lZNYgYRZmEchdxTuNxc=
+github.com/NeowayLabs/drm v0.0.0-20190824133025-4939fc0ad345/go.mod h1:B8Pf8lJWIsLTs7oyWkXOWOGAZiQQVomlZurKAgx8HBA=
+github.com/andybalholm/c2go v0.0.0-20190812182517-7b628d7f3263 h1:o0G+uwnJKYsBvCasVWQbNJpwZIgdrZojjIZ2gD11As4=
+github.com/andybalholm/c2go v0.0.0-20190812182517-7b628d7f3263/go.mod h1:yFSerWaWzARdXE/bre4DLsK+/udgD8LXn2BsaJVdtE0=
+github.com/dkolbly/wl v0.0.0-20180220001605-b06f57e7e2e6 h1:boaySJl2jhPwf+lSBRugRERVEZ0ovAwppOBx73P6zoM=
+github.com/dkolbly/wl v0.0.0-20180220001605-b06f57e7e2e6/go.mod h1:fUuzU55URBTyjoKP2pYoAoeZd1SvdjJP4IkYoT21xZg=
+github.com/elliotchance/c2go v0.25.9 h1:Ju0Kpvhmqw0yJzaf+rsOnno07C/GeFEqSc5hYGip7/U=
+github.com/elliotchance/c2go v0.25.9/go.mod h1:+YFuwnXljn61f5sFHSZ66eH9KTjzzSU6QG1sZdg1l7s=
 github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
 github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
 golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 h1:/zi0zzlPHWXYXrO1LjNRByFu8sdGgCkj2JLDdBIB84k=
 golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/tools v0.0.0-20181109182537-4e34152f1676 h1:mN8PuedDn93qQ+61nw3sKgjrKb7T8lx8DpUI2LwPH5U=
+golang.org/x/tools v0.0.0-20181109182537-4e34152f1676/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

+ 206 - 122
os/linux/input/input_linux.go

@@ -6,18 +6,20 @@ import "gitlab.com/beoran/galago/os/linux"
 import "strings"
 import "os"
 import "unsafe"
-import syscall "golang.org/x/sys/unix"
+import "golang.org/x/sys/unix"
 import "fmt"
 import "path/filepath"
 import "time"
 import "sync"
 import "runtime"
+import "syscall"
 
 
 // Device models an input device
 type Device struct {
     FileName string 
     *os.File
+    syscall.RawConn
     // Cached device information
     Info struct { 
         Events          []SupportedEvent
@@ -30,6 +32,16 @@ type Device struct {
 }
 
 const Directory = "/dev/input"
+var DoLogDebug = false
+
+func LogDebug(format string, args...interface{}) {
+    if !DoLogDebug {
+        return
+    }
+    LogDebug(format, args...)
+}
+
+
 
 func (d * Device) KeepAlive() {
     runtime.KeepAlive(d.File)
@@ -44,19 +56,25 @@ func (d * Device) String() string {
 
 func Open(name string) (*Device, error) {
     f, err := os.OpenFile(filepath.Join(Directory, name), 
-        syscall.O_ASYNC|syscall.O_NONBLOCK|os.O_RDWR, 0666)
+        unix.O_ASYNC|unix.O_NONBLOCK|os.O_RDWR, 0666)
     if err != nil {
         return nil, err
     }
-    if err = syscall.SetNonblock(int(f.Fd()), true); err != nil {
+    if err = unix.SetNonblock(int(f.Fd()), true); err != nil {
+        return nil, err
+    }
+    flags, err := unix.FcntlInt(f.Fd(), unix.F_GETFL, 0);
+    if flags, err = unix.FcntlInt(f.Fd(), unix.F_SETFL, flags | unix.O_NONBLOCK); err != nil {
         return nil, err
     }
-    flags, err := syscall.FcntlInt(f.Fd(), syscall.F_GETFL, 0);
-    if flags, err = syscall.FcntlInt(f.Fd(), syscall.F_SETFL, flags | syscall.O_NONBLOCK); err != nil {
+    
+    rawConn, err := f.SyscallConn()
+    
+    if err != nil {
         return nil, err
     }
     
-    return &Device{FileName: name, File: f}, nil
+    return &Device{FileName: name, File: f, RawConn: rawConn}, nil
 }
 
 func (d *Device) GatherInfo() error {
@@ -115,20 +133,100 @@ func List() ([]string, error) {
 
 // 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(
-        syscall.SYS_IOCTL,
-        uintptr(d.Fd()),
-        uintptr(code),
-        uintptr(pointer))
-    if (errno != 0) {
-        return errno
-    }
-    d.KeepAlive()
-    return nil
+    var errno syscall.Errno = 0 
+    ioctler := func (fd uintptr) {
+        LogDebug("ioctl: %d %d %d\n", uintptr(fd), uintptr(code), uintptr(pointer))
+        _, _, errno = unix.Syscall(
+            unix.SYS_IOCTL,
+            uintptr(fd),
+            uintptr(code),
+            uintptr(pointer))
+    }
+    err2 := d.Control(ioctler)
+    if err2 != nil {
+        return err2
+    }
+    if errno == 0 {
+        return nil
+    }
+    return errno
+}
+
+// Read performs a read unix on the given device. The read is noblocking
+// and will retrn 0 if EAGEIN was raised.
+func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
+    var errno syscall.Errno = 0 
+    var read uintptr = 0
+    reader := func (fd uintptr) bool {
+        LogDebug("read: %d %d %d\n", uintptr(fd), uintptr(pointer), uintptr(size))
+        read, _, errno = unix.Syscall(
+            unix.SYS_READ,
+            uintptr(fd),
+            uintptr(pointer),
+            uintptr(size))
+        return true
+    }
+    err2 := d.RawConn.Read(reader)
+    if err2 != nil {
+        return read, err2
+    }
+    if errno == 0 {
+        return read, nil
+    }
+    if errno == syscall.EAGAIN {
+        return 0, nil
+    }
+    return read, errno
+}
+
+// Read performs a read unix on the given device. The read is blocking.
+func (d * Device) ReadBlock(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
+    var errno syscall.Errno = 0 
+    var read uintptr = 0
+    reader := func (fd uintptr) bool {
+        LogDebug("read: %d %d %d\n", uintptr(fd), uintptr(pointer), uintptr(size))
+        read, _, errno = unix.Syscall(
+            unix.SYS_READ,
+            uintptr(fd),
+            uintptr(pointer),
+            uintptr(size))
+        return errno != syscall.EAGAIN
+    }
+    err2 := d.RawConn.Read(reader)
+    if err2 != nil {
+        return read, err2
+    }
+    if errno == 0 {
+        return read, nil
+    }
+    return read, errno
+}
+
+// Write performs a write unix on the given device. The write is blocking.
+func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
+    var errno syscall.Errno = 0 
+    var wrote uintptr = 0
+    writer := func(fd uintptr) bool {
+        LogDebug("write: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
+        wrote, _, errno = unix.Syscall(
+            unix.SYS_WRITE,
+            uintptr(d.Fd()),
+            uintptr(pointer),
+            uintptr(size))
+        return errno != syscall.EAGAIN
+    }
+    err2 := d.RawConn.Write(writer)
+    if err2 != nil {
+        return wrote, err2
+    }
+    if errno == 0 {
+        return wrote, nil
+    }
+    return wrote, errno
 }
 
 
+
 func (d * Device) DriverVersion() (int32, error) {
     res := int32(0) 
     data := unsafe.Pointer(&res)
@@ -158,6 +256,7 @@ func (d * Device) Id() (linux.INPUT_id, error) {
 // To avoid this, we use a byte array instead, which might lessen performance,
 // but is much easier to use.
 
+// This is a unsafe.Sizeof trick, which I hope will keep working.
 const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))      
 const BITS_PER_LONG = SIZEOF_LONG * 8
 
@@ -196,7 +295,7 @@ func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
     if err != nil {
         return nil, err
     }
-    fmt.Printf("size %d, bits: %v\n", size, bits)
+    LogDebug("size %d, bits: %v\n", size, bits)
     result := []SupportedEvent{}
     for i := uint(0); i < uint(linux.EV_MAX); i++ {
         if (TestBit(bits[0:len(bits)],i)) {
@@ -209,7 +308,6 @@ func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
 
 // More Go-like names for the low leve kernel api structs
 
-
 type InputAbsinfo linux.INPUT_absinfo
 type InputEvent linux.INPUT_event
 
@@ -247,37 +345,6 @@ func (ev InputEvent) String() string {
 }
 
 
-// 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))
-    d.KeepAlive()
-
-    if (errno != 0) {
-        return read, errno
-    }
-    return read, nil
-}
-
-// Write performs a write syscall on the given device
-func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
-    fmt.Printf("write: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
-    wrote, _, errno := syscall.Syscall(
-        syscall.SYS_WRITE,
-        uintptr(d.Fd()),
-        uintptr(pointer),
-        uintptr(size))
-    d.KeepAlive()
-
-    if (errno != 0) {
-        return wrote, errno
-    }
-    return wrote, nil
-}
 
 
 const READ_EVENTS_MAX = 64
@@ -288,11 +355,23 @@ func (d * Device) ReadEvents() ([]InputEvent, error) {
     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) ReadEventsBlock() ([]InputEvent, error) {
+    var events [READ_EVENTS_MAX]InputEvent
+    size := unsafe.Sizeof(events)
+    read, err := d.ReadBlock(unsafe.Pointer(&events), size) 
+    if err != nil {
+        return nil, err
+    }
+    len := read / unsafe.Sizeof(events[0])
+    return events[0:len], nil
+}
+
+
 const WRITE_EVENTS_MAX = 64
 
 func (d * Device) WriteEvents(events []InputEvent) (uint, error) {
@@ -312,10 +391,10 @@ func (d * Device) SupportedAxes() ([]AbsoluteAxis, error) {
         return nil, err
     }
     result := []AbsoluteAxis{}
-    fmt.Printf("Supported Absolute axes:\n");
+    LogDebug("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))
+            LogDebug("  Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
             err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
             if err != nil {
                 return result, err
@@ -345,7 +424,7 @@ func (d * Device) SupportedKeys() ([]SupportedKey, error) {
     if err != nil {
         return nil, err
     }
-    fmt.Printf("size %d, bits: %v\n", size, bits)
+    LogDebug("size %d, bits: %v\n", size, bits)
     result := []SupportedKey{}
     for i := uint(0); i < uint(linux.KEY_MAX); i++ {
         if (TestBit(bits[0:len(bits)],i)) {
@@ -372,7 +451,7 @@ func (d * Device) SupportedRelatives() ([]RelativeAxis, error) {
     if err != nil {
         return nil, err
     }
-    fmt.Printf("size %d, bits: %v\n", size, bits)
+    LogDebug("size %d, bits: %v\n", size, bits)
     result := []RelativeAxis{}
     for i := uint(0); i < uint(linux.REL_MAX); i++ {
         if (TestBit(bits[0:len(bits)],i)) {
@@ -385,10 +464,10 @@ func (d * Device) SupportedRelatives() ([]RelativeAxis, error) {
 
 
 
-// MANAGER_DEVICE_SCAN_DELAY is the delay between device scans for the device manager.  
+// MANAGER_DEVICE_SCAN_DELAY is the delay between device scans for the device driver.  
 const MANAGER_DEVICE_SCAN_DELAY = 3 * time.Second
 
-type Manager struct {
+type Driver struct {
     sync.Mutex
     Connect chan(*Device) 
     Disconnect chan(*Device)
@@ -399,100 +478,105 @@ type Manager struct {
     DevicesByName map[string] *Device
     DevicesByFd map[int] *Device
     Verbose bool
-    fds []syscall.PollFd
-}
-
-
-func NewManager(connect chan(*Device), disconnect chan(*Device), event chan(InputEvent), errors chan(error), done chan (struct{})) * Manager {
-    manager := &Manager{Connect: connect, Disconnect: disconnect, Errors: errors, Done: false}
-    manager.Events = event
-    manager.Devices = []*Device{}
-    manager.DevicesByName = make(map[string] *Device)
-    manager.DevicesByFd = make(map[int] *Device)
-    manager.fds = []syscall.PollFd{}
-    return manager
+    fds []unix.PollFd
+}
+
+
+func NewDriver() * Driver {
+    eveChan := make(chan InputEvent)
+    conChan := make(chan *Device)
+    disChan := make(chan *Device)
+    errChan := make(chan error)
+    driver := &Driver{Connect: conChan, Disconnect: disChan, Errors: errChan,
+        Events: eveChan, 
+        Done: false}
+    driver.Devices = []*Device{}
+    driver.DevicesByName = make(map[string] *Device)
+    driver.DevicesByFd = make(map[int] *Device)
+    driver.fds = []unix.PollFd{}
+    return driver
 } 
 
-func (manager *Manager) connectDevice(device * Device) {
-    manager.Lock()
-    defer manager.Unlock()
-    manager.DevicesByName[device.FileName] = device
-    manager.DevicesByFd[int(device.Fd())] = device
-    manager.Devices = append(manager.Devices, device)
-    pollfd := syscall.PollFd{Fd: int32(device.Fd()), Events : syscall.POLLIN}
-    manager.fds = append(manager.fds, pollfd) 
-    manager.Connect <- device
-}
-
-func (manager *Manager) disconnectDevice(device * Device) {
-    manager.Lock()
-    defer manager.Unlock()
-    delete(manager.DevicesByName, device.FileName)
-    delete(manager.DevicesByFd, int(device.Fd()))
+func (driver *Driver) connectDevice(device * Device) {
+    driver.Lock()
+    defer driver.Unlock()
+    driver.DevicesByName[device.FileName] = device
+    driver.DevicesByFd[int(device.Fd())] = device
+    driver.Devices = append(driver.Devices, device)
+    pollfd := unix.PollFd{Fd: int32(device.Fd()), Events : unix.POLLIN}
+    driver.fds = append(driver.fds, pollfd) 
+    driver.Connect <- device
+}
+
+func (driver *Driver) disconnectDevice(device * Device) {
+    driver.Lock()
+    defer driver.Unlock()
+    delete(driver.DevicesByName, device.FileName)
+    delete(driver.DevicesByFd, int(device.Fd()))
     found := false
     var i int
-    var pollfd syscall.PollFd
-    for i, pollfd = range manager.fds {
+    var pollfd unix.PollFd
+    for i, pollfd = range driver.fds {
         if pollfd.Fd == int32(device.Fd()) {
             found = true 
             break
         }
     }
     if found { 
-        manager.fds = append(manager.fds[:i], manager.fds[(i+1):]...)
-        manager.Devices = append(manager.Devices[:i], manager.Devices[(i+1):]...)
-        manager.Disconnect <- device
+        driver.fds = append(driver.fds[:i], driver.fds[(i+1):]...)
+        driver.Devices = append(driver.Devices[:i], driver.Devices[(i+1):]...)
+        driver.Disconnect <- device
     }
 }
 
-func (manager * Manager) ManageNewDevicesOnce() {
+func (driver * Driver) ManageNewDevicesOnce() {
     fmt.Println("ManageNewDevicesOnce")
     names, err := List()
     if err != nil { 
-        manager.Errors <- err
+        driver.Errors <- err
     } else {
         for _, name := range names {
-            if _, found := manager.DevicesByName[name] ; !found {
+            if _, found := driver.DevicesByName[name] ; !found {
                 device, err := OpenAndGatherInfo(name)
                 if err == nil {
-                    manager.connectDevice(device)
-                } else if manager.Verbose {
-                    manager.Errors <- err
+                    driver.connectDevice(device)
+                } else if driver.Verbose {
+                    driver.Errors <- err
                 }
             }
         }
     }
 }
 
-func (manager *Manager) ReadEventsOnce(device * Device) {
+func (driver *Driver) ReadEventsOnce(device * Device) {
     events, err := device.ReadEvents()
     if err != nil {
-        manager.Errors <- err
-        manager.disconnectDevice(device)
+        driver.Errors <- err
+        driver.disconnectDevice(device)
     } else {
         for _, event := range events {
-            manager.Events <- event
+            driver.Events <- event
         }
     }
 }
 
-func (manager *Manager) ManageInputOnce() {
-    res, err := syscall.Poll(manager.fds, 0) 
+func (driver *Driver) ManageInputOnce() {
+    res, err := unix.Poll(driver.fds, 0) 
     if err != nil {
-        manager.Errors <- err
+        driver.Errors <- err
     }
     if res > 0 { 
-        for _, fd := range manager.fds {
-            if (fd.Revents & syscall.POLLIN) != 0 {
-                device, ok := manager.DevicesByFd[int(fd.Fd)] 
+        for _, fd := range driver.fds {
+            if (fd.Revents & unix.POLLIN) != 0 {
+                device, ok := driver.DevicesByFd[int(fd.Fd)] 
                 if ok && device != nil {
-                    manager.ReadEventsOnce(device)
+                    driver.ReadEventsOnce(device)
                 }
             }
-            if (fd.Revents & syscall.POLLHUP) != 0 {
-                device, ok := manager.DevicesByFd[int(fd.Fd)] 
+            if (fd.Revents & unix.POLLHUP) != 0 {
+                device, ok := driver.DevicesByFd[int(fd.Fd)] 
                 if ok && device != nil {
-                    manager.disconnectDevice(device)
+                    driver.disconnectDevice(device)
                 }
             }
 
@@ -500,27 +584,27 @@ func (manager *Manager) ManageInputOnce() {
     }
 }
 
-func (manager *Manager) ManageDevices() {
-    for !manager.Done {
-        manager.ManageNewDevicesOnce()
+func (driver *Driver) ManageDevices() {
+    for !driver.Done {
+        driver.ManageNewDevicesOnce()
         time.Sleep(MANAGER_DEVICE_SCAN_DELAY)
     }
 }
 
-func (manager *Manager) ManageInput() {
-    for !manager.Done {
-        manager.ManageInputOnce()
+func (driver *Driver) ManageInput() {
+    for !driver.Done {
+        driver.ManageInputOnce()
     }
 }
 
-func (manager *Manager) Start() {
-    go manager.ManageDevices()
-    go manager.ManageInput()
+func (driver *Driver) Start() {
+    go driver.ManageDevices()
+    go driver.ManageInput()
 }
 
-func (manager *Manager) Stop() {
-    manager.Lock() ; defer manager.Unlock()
-    manager.Done = true
+func (driver *Driver) Stop() {
+    driver.Lock() ; defer driver.Unlock()
+    driver.Done = true
 }
 
 

+ 27 - 12
os/linux/input/input_linux_test.go

@@ -176,37 +176,52 @@ func TestReadEvents(t * testing.T) {
     }
 }
 
-func TestManager(t * testing.T) {
-    eveChan := make(chan InputEvent)
-    errChan := make(chan error)
-    conChan := make(chan *Device)
-    disChan := make(chan *Device)
-    donChan := make(chan struct{})
-    manager := NewManager(conChan, disChan, eveChan, errChan, donChan)
+func TestReadEventsBlock(t * testing.T) {
+    device , err := Open(IN)
+    if err != nil {
+        t.Errorf("Error Open: %s\n", err)
+        return
+    }
+    defer device.Close()
+    events, err := device.ReadEventsBlock()
+    if err != nil {
+        t.Errorf("Error ReadEvents: %s\n", err)
+        return
+    }
+    
+    t.Logf("Events:\n")
+	for i, ev := range events {
+        t.Logf("Event: %d: %s\n", i, ev.String())
+    }
+}
+
+
+func TestDriver(t * testing.T) {
+    driver := NewDriver()
     done := false
     go func() { 
             for !done {
-                dev := <- conChan
+                dev := <- driver.Connect
                 fmt.Printf("Connected: %s\n", dev.String())  
             }
         }()
     go func() { 
             for !done {
-                dev := <- disChan
+                dev := <- driver.Disconnect
                 fmt.Printf("Disconnected: %s\n", dev.String())  
             }
         }()
 
     go func() {
             for !done {
-                err := <- errChan
+                err := <- driver.Errors
                 fmt.Printf("Error: %s\n", err)  
             }
         }()
           
     go func() { 
             for !done {
-                eve := <- eveChan
+                eve := <- driver.Events
                 fmt.Printf("%s\n", eve.String())
                 if eve.Type == linux.EV_KEY && eve.Code == linux.BTN_JOYSTICK {
                     done = true
@@ -214,7 +229,7 @@ func TestManager(t * testing.T) {
             }
         }()
 
-    manager.Start()
+    driver.Start()
     for ! done {
         time.Sleep(1 * time.Second)
     }

+ 1 - 1
os/linux/linux32.go

@@ -8,7 +8,7 @@
 package linux
 
 
-// platform specific for 64 bits linux platforms
+// platform specific type aliases for 64 bits linux platforms
 
 
 type Long = int32

+ 1 - 1
os/linux/linux64.go

@@ -5,7 +5,7 @@
 
 package linux
 
-// platform specific for 64 bits linux platforms
+// platform specific type aliases for 64 bits linux platforms
 
 type Long = int64