Browse Source

Work on inpput manager.

Beoran 4 years ago
parent
commit
f298cd9e20
1 changed files with 78 additions and 2 deletions
  1. 78 2
      os/linux/input/input_linux.go

+ 78 - 2
os/linux/input/input_linux.go

@@ -14,7 +14,8 @@ import "runtime"
 
 
 // Device models an input device
-type Device struct { 
+type Device struct {
+    FileName string 
     *os.File
 }
 
@@ -33,7 +34,12 @@ func Open(name string) (*Device, error) {
     if err = syscall.SetNonblock(int(f.Fd()), true); err != nil {
         return nil, err
     }
-    return &Device{File: f}, nil
+    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 {
+        return nil, err
+    }
+    
+    return &Device{FileName: name, File: f}, nil
 } 
 
 func List() ([]string, error) {
@@ -326,6 +332,76 @@ func (d * Device) RelativeAxes() ([]RelativeAxis, error) {
 }
 
 
+type Manager struct {
+    Connect chan(*Device) 
+    Disconnect chan(*Device)
+    Errors chan(error) 
+    Done bool
+    Devices []*Device
+    DevicesByName map[string] *Device
+    DevicesByFd map[int] *Device
+    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.Devices = []*Device{}
+    manager.DevicesByName = make(map[string] *Device)
+    manager.DevicesByFd = make(map[int] *Device)
+    manager.fds = []syscall.PollFd{}
+    return manager
+} 
+
+func (manager *Manager) connectDevice(device * Device) {
+    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) {
+    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
+}
+
+func (manager * Manager) ManageNewDevicesOnce() {
+    names, err := List()
+    if err != nil { 
+        manager.Errors <- err
+    } else {
+        for _, name := range names {
+            if _, found := manager.DevicesByName[name] ; !found {
+                device, err := Open(name)
+                if err != nil {
+                    manager.connectDevice(device)
+                } else {
+                    manager.Errors <- err
+                }
+            }
+        }
+    }
+}
+
+func (manager *Manager) ManageInputOnce() {
+    res, err := syscall.Poll(manager.fds, 0) 
+    if err != nil {
+        manager.Errors <- err
+    }
+    if res > 0 { 
+        for _, fd := range manager.fds {
+            if (fd.Revents & syscall.POLLIN) != 0 {
+                
+            }
+        }
+    }
+}
 
 
 /*