Browse Source

WIP input manager for Linux.

Beoran 4 years ago
parent
commit
f5b30e132a
1 changed files with 34 additions and 7 deletions
  1. 34 7
      os/linux/input/input_linux.go

+ 34 - 7
os/linux/input/input_linux.go

@@ -335,7 +335,8 @@ func (d * Device) RelativeAxes() ([]RelativeAxis, error) {
 type Manager struct {
     Connect chan(*Device) 
     Disconnect chan(*Device)
-    Errors chan(error) 
+    Errors chan(error)
+    Events chan(InputEvent) 
     Done bool
     Devices []*Device
     DevicesByName map[string] *Device
@@ -346,6 +347,7 @@ type Manager struct {
 
 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)
@@ -365,10 +367,20 @@ func (manager *Manager) connectDevice(device * Device) {
 func (manager *Manager) disconnectDevice(device * Device) {
     delete(manager.DevicesByName, device.FileName)
     delete(manager.DevicesByFd, int(device.Fd()))
-    // XXX: manager.Devices = append(manager.Devices, device)
-    // pollfd := sycall.PollFd{Fd: device.Fd(), Events : syscall.POLLIN}
-    // manager.fds = append(manager.fds, pollfd) 
-    manager.Disconnect <- device
+    found := false
+    var i int
+    var pollfd syscall.PollFd
+    for i, pollfd = range manager.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
+    }
 }
 
 func (manager * Manager) ManageNewDevicesOnce() {
@@ -379,7 +391,7 @@ func (manager * Manager) ManageNewDevicesOnce() {
         for _, name := range names {
             if _, found := manager.DevicesByName[name] ; !found {
                 device, err := Open(name)
-                if err != nil {
+                if err == nil {
                     manager.connectDevice(device)
                 } else {
                     manager.Errors <- err
@@ -389,6 +401,18 @@ func (manager * Manager) ManageNewDevicesOnce() {
     }
 }
 
+func (manager *Manager) ReadEventsOnce(device * Device) {
+    events, err := device.ReadEvents()
+    if err != nil {
+        manager.Errors <- err
+        manager.disconnectDevice(device)
+    } else {
+        for _, event := range events {
+            manager.Events <- event
+        }
+    }
+}
+
 func (manager *Manager) ManageInputOnce() {
     res, err := syscall.Poll(manager.fds, 0) 
     if err != nil {
@@ -397,7 +421,10 @@ func (manager *Manager) ManageInputOnce() {
     if res > 0 { 
         for _, fd := range manager.fds {
             if (fd.Revents & syscall.POLLIN) != 0 {
-                
+                device, ok := manager.DevicesByFd[int(fd.Fd)] 
+                if ok && device != nil {
+                    manager.ReadEventsOnce(device)
+                }
             }
         }
     }