|
@@ -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) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
+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");
|