Browse Source

Input manager actually works fine, but testing.Logf is buffered, so don't use that in a live test.

Beoran 4 years ago
parent
commit
29bc76a0e5
2 changed files with 90 additions and 3 deletions
  1. 42 1
      os/linux/input/input_linux.go
  2. 48 2
      os/linux/input/input_linux_test.go

+ 42 - 1
os/linux/input/input_linux.go

@@ -10,6 +10,7 @@ import syscall "golang.org/x/sys/unix"
 import "fmt"
 import "path/filepath"
 import "time"
+import "sync"
 import "runtime"
 
 
@@ -332,7 +333,11 @@ func (d * Device) RelativeAxes() ([]RelativeAxis, error) {
 }
 
 
+// MANAGER_DEVICE_SCAN_DELAY is the delay between device scans for the device manager.  
+const MANAGER_DEVICE_SCAN_DELAY = 3 * time.Second
+
 type Manager struct {
+    sync.Mutex
     Connect chan(*Device) 
     Disconnect chan(*Device)
     Errors chan(error)
@@ -341,6 +346,7 @@ type Manager struct {
     Devices []*Device
     DevicesByName map[string] *Device
     DevicesByFd map[int] *Device
+    Verbose bool
     fds []syscall.PollFd
 }
 
@@ -356,6 +362,8 @@ func NewManager(connect chan(*Device), disconnect chan(*Device), event chan(Inpu
 } 
 
 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)
@@ -365,6 +373,8 @@ func (manager *Manager) connectDevice(device * Device) {
 }
 
 func (manager *Manager) disconnectDevice(device * Device) {
+    manager.Lock()
+    defer manager.Unlock()
     delete(manager.DevicesByName, device.FileName)
     delete(manager.DevicesByFd, int(device.Fd()))
     found := false
@@ -384,6 +394,7 @@ func (manager *Manager) disconnectDevice(device * Device) {
 }
 
 func (manager * Manager) ManageNewDevicesOnce() {
+    fmt.Println("ManageNewDevicesOnce")
     names, err := List()
     if err != nil { 
         manager.Errors <- err
@@ -393,7 +404,7 @@ func (manager * Manager) ManageNewDevicesOnce() {
                 device, err := Open(name)
                 if err == nil {
                     manager.connectDevice(device)
-                } else {
+                } else if manager.Verbose {
                     manager.Errors <- err
                 }
             }
@@ -426,10 +437,40 @@ func (manager *Manager) ManageInputOnce() {
                     manager.ReadEventsOnce(device)
                 }
             }
+            if (fd.Revents & syscall.POLLHUP) != 0 {
+                device, ok := manager.DevicesByFd[int(fd.Fd)] 
+                if ok && device != nil {
+                    manager.disconnectDevice(device)
+                }
+            }
+
         }
     }
 }
 
+func (manager *Manager) ManageDevices() {
+    for !manager.Done {
+        manager.ManageNewDevicesOnce()
+        time.Sleep(MANAGER_DEVICE_SCAN_DELAY)
+    }
+}
+
+func (manager *Manager) ManageInput() {
+    for !manager.Done {
+        manager.ManageInputOnce()
+    }
+}
+
+func (manager *Manager) Start() {
+    go manager.ManageDevices()
+    go manager.ManageInput()
+}
+
+func (manager *Manager) Stop() {
+    manager.Lock() ; defer manager.Unlock()
+    manager.Done = true
+}
+
 
 /*    
 	printf("Supported events:\n");

+ 48 - 2
os/linux/input/input_linux_test.go

@@ -1,9 +1,10 @@
 package input
 
 import "testing"
+import "time"
 // import "os"
 // import "syscall"
-// import "fmt"
+import "fmt"
 import "gitlab.com/beoran/galago/os/linux"
 
 
@@ -141,7 +142,7 @@ func TestSupportedAxes(t * testing.T) {
 
 
 func TestRelativeAxes(t * testing.T) {
-    device , err := Open(IN2)
+    device , err := Open(IN)
     if err != nil {
         t.Errorf("Error Open: %s\n", err)
         return
@@ -175,4 +176,49 @@ 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)
+    done := false
+    go func() { 
+            for !done {
+                dev := <- conChan
+                fmt.Printf("Connected: %s\n", dev.FileName)  
+            }
+        }()
+    go func() { 
+            for !done {
+                dev := <- disChan
+                fmt.Printf("Disconnected: %s\n", dev.FileName)  
+            }
+        }()
+
+    go func() {
+            for !done {
+                err := <- errChan
+                fmt.Printf("Error: %s\n", err)  
+            }
+        }()
+          
+    go func() { 
+            for !done {
+                eve := <- eveChan
+                fmt.Printf("%s\n", eve.String())
+                if eve.Type == linux.EV_KEY && eve.Code == linux.BTN_JOYSTICK {
+                    done = true
+                }   
+            }
+        }()
+
+    manager.Start()
+    for ! done {
+        time.Sleep(1 * time.Second)
+    }
+    done = true
+}
+