input_linux.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /* package input is a thing Go wrapper around the Linux kernel input event
  2. * system. */
  3. package input
  4. import "gitlab.com/beoran/galago/os/linux"
  5. import "strings"
  6. import "os"
  7. import "unsafe"
  8. import "golang.org/x/sys/unix"
  9. import "fmt"
  10. import "path/filepath"
  11. import "time"
  12. import "sync"
  13. import "runtime"
  14. import "syscall"
  15. // Device models an input device
  16. type Device struct {
  17. FileName string
  18. fd int
  19. // Cached device information
  20. Info struct {
  21. Events []SupportedEvent
  22. Keys []SupportedKey
  23. Axes []AbsoluteAxis
  24. Rolls []RelativeAxis
  25. Name string
  26. ID string
  27. }
  28. }
  29. const Directory = "/dev/input"
  30. var DoLogDebug = false
  31. func LogDebug(format string, args...interface{}) {
  32. if !DoLogDebug {
  33. return
  34. }
  35. LogDebug(format, args...)
  36. }
  37. func (d * Device) KeepAlive() {
  38. runtime.KeepAlive(d)
  39. }
  40. func (d * Device) String() string {
  41. return fmt.Sprintf("%s: %s (%s):%v,%v,%v,%v",
  42. d.FileName, d.Info.Name, d.Info.ID,
  43. d.Info.Events, d.Info.Axes, d.Info.Keys,
  44. d.Info.Rolls)
  45. }
  46. func (d *Device) SetNonblock(nonblocking bool) error {
  47. err := unix.SetNonblock(int(d.fd), nonblocking)
  48. return err
  49. }
  50. func Open(name string) (*Device, error) {
  51. path := filepath.Join(Directory, name)
  52. fd, err := unix.Open(path, unix.O_ASYNC|unix.O_NONBLOCK|unix.O_RDWR, 0666)
  53. if err != nil {
  54. return nil, err
  55. }
  56. device := &Device{FileName: name, fd: fd}
  57. if err = device.SetNonblock(true) ; err != nil {
  58. return nil, err
  59. }
  60. runtime.SetFinalizer(device, (*Device).Close)
  61. return device, nil
  62. }
  63. func (d *Device) GatherInfo() error {
  64. var err error
  65. if d.Info.Events, err = d.SupportedEvents(); err != nil {
  66. return err
  67. }
  68. if d.Info.Keys, err = d.SupportedKeys(); err != nil {
  69. return err
  70. }
  71. if d.Info.Axes, err = d.SupportedAxes(); err != nil {
  72. return err
  73. }
  74. if d.Info.Rolls, err = d.SupportedRelatives(); err != nil {
  75. return err
  76. }
  77. if id, err := d.Id(); err != nil {
  78. return err
  79. } else {
  80. d.Info.ID = fmt.Sprintf("%v", id)
  81. }
  82. if d.Info.Name, err = d.Name(); err != nil {
  83. return err
  84. }
  85. return nil
  86. }
  87. func OpenAndGatherInfo(name string) (*Device, error) {
  88. dev, err := Open(name)
  89. if err != nil {
  90. return dev, err
  91. }
  92. err = dev.GatherInfo()
  93. return dev, err
  94. }
  95. func List() ([]string, error) {
  96. dir, err := os.Open(Directory)
  97. if err != nil {
  98. return nil, err
  99. }
  100. names, err := dir.Readdirnames(-1)
  101. if err != nil {
  102. return names, err
  103. }
  104. results := names[:0]
  105. for _, name := range names {
  106. if strings.HasPrefix(name, "event") {
  107. results = append(results, name)
  108. }
  109. }
  110. return results, nil
  111. }
  112. // Icotl performs an ioctl on the given device
  113. func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
  114. var errno syscall.Errno = 0
  115. LogDebug("ioctl: %d %d %d\n", uintptr(d.fd), uintptr(code), uintptr(pointer))
  116. _, _, errno = unix.Syscall(
  117. unix.SYS_IOCTL,
  118. uintptr(d.fd),
  119. uintptr(code),
  120. uintptr(pointer))
  121. if errno != 0 {
  122. return errno
  123. }
  124. return nil
  125. }
  126. // Read performs a read unix on the given device. The read is noblocking
  127. // and will retrn 0 if EAGEIN was raised.
  128. func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  129. if d.IsClosed() {
  130. return 0, syscall.EINVAL
  131. }
  132. var errno syscall.Errno = 0
  133. var read uintptr = 0
  134. LogDebug("read: %d %d %d\n", uintptr(d.fd), uintptr(pointer), uintptr(size))
  135. read, _, errno = unix.Syscall(
  136. unix.SYS_READ,
  137. uintptr(d.fd),
  138. uintptr(pointer),
  139. uintptr(size))
  140. if errno == 0 {
  141. return read, nil
  142. }
  143. if errno == syscall.EAGAIN {
  144. return 0, nil
  145. }
  146. return read, errno
  147. }
  148. // Read performs a read unix on the given device. The read is blocking.
  149. func (d * Device) ReadBlock(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  150. read, err := d.Read(pointer, size)
  151. for read < 1 {
  152. if err != nil {
  153. return 0, err
  154. }
  155. read, err = d.Read(pointer, size)
  156. }
  157. return read, err
  158. }
  159. // Write performs a write unix on the given device. The write is blocking.
  160. func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  161. if d.IsClosed() {
  162. return 0, syscall.EINVAL
  163. }
  164. var errno syscall.Errno = syscall.EAGAIN
  165. var wrote uintptr = 0
  166. for errno == syscall.EAGAIN {
  167. LogDebug("write: %d %d %d\n", uintptr(d.fd), uintptr(pointer), uintptr(size))
  168. wrote, _, errno = unix.Syscall(
  169. unix.SYS_WRITE,
  170. uintptr(d.fd),
  171. uintptr(pointer),
  172. uintptr(size))
  173. }
  174. if errno == 0 {
  175. return wrote, nil
  176. }
  177. return wrote, errno
  178. }
  179. func (d * Device) IsClosed() bool {
  180. return d.fd < 0
  181. }
  182. // Close closes the device
  183. func (d * Device) Close() error {
  184. if d.IsClosed() {
  185. return nil
  186. }
  187. err := unix.Close(d.fd)
  188. if err != nil {
  189. return err
  190. }
  191. return nil
  192. }
  193. func (d * Device) DriverVersion() (int32, error) {
  194. res := int32(0)
  195. data := unsafe.Pointer(&res)
  196. err := d.Ioctl(linux.EVIOCGVERSION, data)
  197. return res, err
  198. }
  199. const NAME_MAX = 256
  200. func (d * Device) Name() (string, error) {
  201. buffer := [NAME_MAX]byte{}
  202. err := d.Ioctl(linux.EVIOCGNAME(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  203. return string(buffer[0:len(buffer)]), err
  204. }
  205. func (d * Device) Id() (linux.INPUT_id, error) {
  206. var result linux.INPUT_id
  207. err := d.Ioctl(linux.EVIOCGID, unsafe.Pointer(&result))
  208. return result, err
  209. }
  210. // The Linux developers thought it was a great idea a to use an array of
  211. // unsigned longs for the bit flags of input devices. Of course, the length
  212. // of an unsigned long is platform dependent which then entails all sorts of
  213. // gymnastics to extract the bits from the array.
  214. // To avoid this, we use a byte array instead, which might lessen performance,
  215. // but is much easier to use.
  216. // This is a unsafe.Sizeof trick, which I hope will keep working.
  217. const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))
  218. const BITS_PER_LONG = SIZEOF_LONG * 8
  219. func BitsToLong(bits uint) uint {
  220. return ((bits) + (8 * SIZEOF_LONG) - 1) / (8 * SIZEOF_LONG)
  221. }
  222. const TOPOLOGY_MAX = 256
  223. func (d * Device) Topology() (string, error) {
  224. buffer := [TOPOLOGY_MAX]byte{}
  225. err := d.Ioctl(linux.EVIOCGPHYS(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  226. return string(buffer[0:len(buffer)]), err
  227. }
  228. func TestBit(array []uint8, bit uint) bool {
  229. elem := uint(array[ bit / 8 ])
  230. flag := uint(1) << uint(bit % 8)
  231. return (elem & flag ) != 0
  232. }
  233. type SupportedEvent uint
  234. func (se SupportedEvent) Name() string {
  235. return linux.EvToString(uint(se))
  236. }
  237. func (se SupportedEvent) String() string {
  238. return se.Name()
  239. }
  240. func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
  241. var bits [linux.EV_MAX / 8 + 1]uint8
  242. size := unsafe.Sizeof(bits)
  243. err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
  244. if err != nil {
  245. return nil, err
  246. }
  247. LogDebug("size %d, bits: %v\n", size, bits)
  248. result := []SupportedEvent{}
  249. for i := uint(0); i < uint(linux.EV_MAX); i++ {
  250. if (TestBit(bits[0:len(bits)],i)) {
  251. result = append(result, SupportedEvent(uint(i)))
  252. }
  253. }
  254. return result, nil
  255. }
  256. // More Go-like names for the low leve kernel api structs
  257. type InputAbsinfo linux.INPUT_absinfo
  258. type InputEvent linux.INPUT_event
  259. type AbsoluteAxis struct {
  260. Index uint
  261. InputAbsinfo
  262. }
  263. func (ax AbsoluteAxis) Name() string {
  264. return linux.AbsToString(ax.Index)
  265. }
  266. func (ax AbsoluteAxis) String() string {
  267. return fmt.Sprintf("%s %d (min:%d max:%d flat:%d fuzz:%d)",
  268. ax.Name(),
  269. ax.Value,
  270. ax.Minimum,
  271. ax.Maximum,
  272. ax.Flat,
  273. ax.Fuzz)
  274. }
  275. func (ev InputEvent) Time() time.Time {
  276. return time.Unix(ev.Timeval.Tv_sec, ev.Timeval.Tv_usec)
  277. }
  278. func (ev InputEvent) String() string {
  279. return fmt.Sprintf("Event: Time: %s Type: %s, Code: %d, Value:%d",
  280. ev.Time().Format("2006-01-02 15:04:05.000000"),
  281. linux.EvToString(uint(ev.Type)),
  282. ev.Code,
  283. ev.Value)
  284. }
  285. const READ_EVENTS_MAX = 64
  286. func (d * Device) ReadEvents() ([]InputEvent, error) {
  287. var events [READ_EVENTS_MAX]InputEvent
  288. size := unsafe.Sizeof(events)
  289. read, err := d.Read(unsafe.Pointer(&events), size)
  290. if err != nil {
  291. return nil, err
  292. }
  293. len := read / unsafe.Sizeof(events[0])
  294. return events[0:len], nil
  295. }
  296. func (d * Device) ReadEventsBlock() ([]InputEvent, error) {
  297. var events [READ_EVENTS_MAX]InputEvent
  298. size := unsafe.Sizeof(events)
  299. read, err := d.ReadBlock(unsafe.Pointer(&events), size)
  300. if err != nil {
  301. return nil, err
  302. }
  303. len := read / unsafe.Sizeof(events[0])
  304. return events[0:len], nil
  305. }
  306. const WRITE_EVENTS_MAX = 64
  307. func (d * Device) WriteEvents(events []InputEvent) (uint, error) {
  308. size := unsafe.Sizeof(events[0]) * uintptr(len(events))
  309. wrote, err := d.Write(unsafe.Pointer(&events[0]), size)
  310. len := uint(wrote / size)
  311. return len, err
  312. }
  313. func (d * Device) SupportedAxes() ([]AbsoluteAxis, error) {
  314. var abs_feat InputAbsinfo;
  315. var abs_b [linux.ABS_MAX/8 + 1]uint8;
  316. size := unsafe.Sizeof(abs_b)
  317. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_ABS, size), unsafe.Pointer(&abs_b))
  318. if err != nil {
  319. return nil, err
  320. }
  321. result := []AbsoluteAxis{}
  322. LogDebug("Supported Absolute axes:\n");
  323. for yalv := uint(0); yalv < linux.ABS_MAX; yalv++ {
  324. if TestBit(abs_b[0:len(abs_b)], uint(yalv)) {
  325. LogDebug(" Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
  326. err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
  327. if err != nil {
  328. return result, err
  329. }
  330. axis := AbsoluteAxis{Index: yalv, InputAbsinfo: abs_feat}
  331. result = append(result, axis)
  332. }
  333. }
  334. return result, nil
  335. }
  336. type SupportedKey uint
  337. func (se SupportedKey) Name() string {
  338. return linux.KeyString(uint(se))
  339. }
  340. func (se SupportedKey) String() string {
  341. return se.Name()
  342. }
  343. func (d * Device) SupportedKeys() ([]SupportedKey, error) {
  344. var bits [linux.KEY_MAX / 8 + 1]uint8
  345. size := unsafe.Sizeof(bits)
  346. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_KEY, uintptr(size)), unsafe.Pointer(&bits));
  347. if err != nil {
  348. return nil, err
  349. }
  350. LogDebug("size %d, bits: %v\n", size, bits)
  351. result := []SupportedKey{}
  352. for i := uint(0); i < uint(linux.KEY_MAX); i++ {
  353. if (TestBit(bits[0:len(bits)],i)) {
  354. result = append(result, SupportedKey(uint(i)))
  355. }
  356. }
  357. return result, nil
  358. }
  359. type RelativeAxis uint
  360. func (se RelativeAxis) Name() string {
  361. return linux.RelString(uint(se))
  362. }
  363. func (se RelativeAxis) String() string {
  364. return se.Name()
  365. }
  366. func (d * Device) SupportedRelatives() ([]RelativeAxis, error) {
  367. var bits [linux.REL_MAX / 8 + 1]uint8
  368. size := unsafe.Sizeof(bits)
  369. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_REL, uintptr(size)), unsafe.Pointer(&bits));
  370. if err != nil {
  371. return nil, err
  372. }
  373. LogDebug("size %d, bits: %v\n", size, bits)
  374. result := []RelativeAxis{}
  375. for i := uint(0); i < uint(linux.REL_MAX); i++ {
  376. if (TestBit(bits[0:len(bits)],i)) {
  377. result = append(result, RelativeAxis(uint(i)))
  378. }
  379. }
  380. return result, nil
  381. }
  382. // MANAGER_DEVICE_SCAN_DELAY is the delay between device scans for the device driver.
  383. const MANAGER_DEVICE_SCAN_DELAY = 3 * time.Second
  384. type Driver struct {
  385. sync.Mutex
  386. Connect chan(*Device)
  387. Disconnect chan(*Device)
  388. Errors chan(error)
  389. Events chan(InputEvent)
  390. Done bool
  391. Devices []*Device
  392. DevicesByName map[string] *Device
  393. DevicesByFd map[int] *Device
  394. Verbose bool
  395. fds []unix.PollFd
  396. }
  397. func NewDriver() * Driver {
  398. eveChan := make(chan InputEvent)
  399. conChan := make(chan *Device)
  400. disChan := make(chan *Device)
  401. errChan := make(chan error)
  402. driver := &Driver{Connect: conChan, Disconnect: disChan, Errors: errChan,
  403. Events: eveChan,
  404. Done: false}
  405. driver.Devices = []*Device{}
  406. driver.DevicesByName = make(map[string] *Device)
  407. driver.DevicesByFd = make(map[int] *Device)
  408. driver.fds = []unix.PollFd{}
  409. return driver
  410. }
  411. func (driver *Driver) connectDevice(device * Device) {
  412. driver.Lock()
  413. defer driver.Unlock()
  414. driver.DevicesByName[device.FileName] = device
  415. driver.DevicesByFd[int(device.fd)] = device
  416. driver.Devices = append(driver.Devices, device)
  417. pollfd := unix.PollFd{Fd: int32(device.fd), Events : unix.POLLIN}
  418. driver.fds = append(driver.fds, pollfd)
  419. driver.Connect <- device
  420. }
  421. func (driver *Driver) disconnectDevice(device * Device) {
  422. driver.Lock()
  423. defer driver.Unlock()
  424. delete(driver.DevicesByName, device.FileName)
  425. delete(driver.DevicesByFd, int(device.fd))
  426. found := false
  427. var i int
  428. var pollfd unix.PollFd
  429. for i, pollfd = range driver.fds {
  430. if pollfd.Fd == int32(device.fd) {
  431. found = true
  432. break
  433. }
  434. }
  435. if found {
  436. driver.fds = append(driver.fds[:i], driver.fds[(i+1):]...)
  437. driver.Devices = append(driver.Devices[:i], driver.Devices[(i+1):]...)
  438. driver.Disconnect <- device
  439. }
  440. }
  441. func (driver * Driver) ManageNewDevicesOnce() {
  442. fmt.Println("ManageNewDevicesOnce")
  443. names, err := List()
  444. if err != nil {
  445. driver.Errors <- err
  446. } else {
  447. for _, name := range names {
  448. if _, found := driver.DevicesByName[name] ; !found {
  449. device, err := OpenAndGatherInfo(name)
  450. if err == nil {
  451. driver.connectDevice(device)
  452. } else if driver.Verbose {
  453. driver.Errors <- err
  454. }
  455. }
  456. }
  457. }
  458. }
  459. func (driver *Driver) ReadEventsOnce(device * Device) {
  460. events, err := device.ReadEvents()
  461. if err != nil {
  462. driver.Errors <- err
  463. driver.disconnectDevice(device)
  464. } else {
  465. for _, event := range events {
  466. driver.Events <- event
  467. }
  468. }
  469. }
  470. func (driver *Driver) ManageInputOnce() {
  471. res, err := unix.Poll(driver.fds, 0)
  472. if err != nil {
  473. driver.Errors <- err
  474. }
  475. if res > 0 {
  476. for _, fd := range driver.fds {
  477. if (fd.Revents & unix.POLLIN) != 0 {
  478. device, ok := driver.DevicesByFd[int(fd.Fd)]
  479. if ok && device != nil {
  480. driver.ReadEventsOnce(device)
  481. }
  482. }
  483. if (fd.Revents & unix.POLLHUP) != 0 {
  484. device, ok := driver.DevicesByFd[int(fd.Fd)]
  485. if ok && device != nil {
  486. driver.disconnectDevice(device)
  487. }
  488. }
  489. }
  490. }
  491. }
  492. func (driver *Driver) ManageDevices() {
  493. for !driver.Done {
  494. driver.ManageNewDevicesOnce()
  495. time.Sleep(MANAGER_DEVICE_SCAN_DELAY)
  496. }
  497. }
  498. func (driver *Driver) ManageInput() {
  499. for !driver.Done {
  500. driver.ManageInputOnce()
  501. }
  502. }
  503. func (driver *Driver) Start() {
  504. go driver.ManageDevices()
  505. go driver.ManageInput()
  506. }
  507. func (driver *Driver) Stop() {
  508. driver.Lock() ; defer driver.Unlock()
  509. driver.Done = true
  510. }