input_linux.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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 syscall "golang.org/x/sys/unix"
  9. import "fmt"
  10. import "path/filepath"
  11. import "time"
  12. import "runtime"
  13. // Device models an input device
  14. type Device struct {
  15. FileName string
  16. *os.File
  17. }
  18. const Directory = "/dev/input"
  19. func (d * Device) KeepAlive() {
  20. runtime.KeepAlive(d.File)
  21. }
  22. func Open(name string) (*Device, error) {
  23. f, err := os.OpenFile(filepath.Join(Directory, name),
  24. syscall.O_ASYNC|syscall.O_NONBLOCK|os.O_RDWR, 0666)
  25. if err != nil {
  26. return nil, err
  27. }
  28. if err = syscall.SetNonblock(int(f.Fd()), true); err != nil {
  29. return nil, err
  30. }
  31. flags, err := syscall.FcntlInt(f.Fd(), syscall.F_GETFL, 0);
  32. if flags, err = syscall.FcntlInt(f.Fd(), syscall.F_SETFL, flags | syscall.O_NONBLOCK); err != nil {
  33. return nil, err
  34. }
  35. return &Device{FileName: name, File: f}, nil
  36. }
  37. func List() ([]string, error) {
  38. dir, err := os.Open(Directory)
  39. if err != nil {
  40. return nil, err
  41. }
  42. names, err := dir.Readdirnames(-1)
  43. if err != nil {
  44. return names, err
  45. }
  46. results := names[:0]
  47. for _, name := range names {
  48. if strings.HasPrefix(name, "event") {
  49. results = append(results, name)
  50. }
  51. }
  52. return results, nil
  53. }
  54. // Icotl performs an ioctl on the given device
  55. func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
  56. fmt.Printf("ioctl: %d %d %d\n", uintptr(d.Fd()), uintptr(code), uintptr(pointer))
  57. _, _, errno := syscall.Syscall(
  58. syscall.SYS_IOCTL,
  59. uintptr(d.Fd()),
  60. uintptr(code),
  61. uintptr(pointer))
  62. if (errno != 0) {
  63. return errno
  64. }
  65. d.KeepAlive()
  66. return nil
  67. }
  68. func (d * Device) DriverVersion() (int32, error) {
  69. res := int32(0)
  70. data := unsafe.Pointer(&res)
  71. err := d.Ioctl(linux.EVIOCGVERSION, data)
  72. return res, err
  73. }
  74. const NAME_MAX = 256
  75. func (d * Device) Name() (string, error) {
  76. buffer := [NAME_MAX]byte{}
  77. err := d.Ioctl(linux.EVIOCGNAME(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  78. return string(buffer[0:len(buffer)]), err
  79. }
  80. func (d * Device) Id() (linux.INPUT_id, error) {
  81. var result linux.INPUT_id
  82. err := d.Ioctl(linux.EVIOCGID, unsafe.Pointer(&result))
  83. return result, err
  84. }
  85. // The Linux developers thought it was a great idea a to use an array of
  86. // unsigned longs for the bit flags of input devices. Of course, the length
  87. // of an unsigned long is platform dependent which then entails all sorts of
  88. // gymnastics to extract the bits from the array.
  89. // To avoid this, we use a byte array instead, which might lessen performance,
  90. // but is much easier to use.
  91. const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))
  92. const BITS_PER_LONG = SIZEOF_LONG * 8
  93. func BitsToLong(bits uint) uint {
  94. return ((bits) + (8 * SIZEOF_LONG) - 1) / (8 * SIZEOF_LONG)
  95. }
  96. const TOPOLOGY_MAX = 256
  97. func (d * Device) Topology() (string, error) {
  98. buffer := [TOPOLOGY_MAX]byte{}
  99. err := d.Ioctl(linux.EVIOCGPHYS(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  100. return string(buffer[0:len(buffer)]), err
  101. }
  102. func TestBit(array []uint8, bit uint) bool {
  103. elem := uint(array[ bit / 8 ])
  104. flag := uint(1) << uint(bit % 8)
  105. return (elem & flag ) != 0
  106. }
  107. type SupportedEvent uint
  108. func (se SupportedEvent) Name() string {
  109. return linux.EvToString(uint(se))
  110. }
  111. func (se SupportedEvent) String() string {
  112. return se.Name()
  113. }
  114. func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
  115. var bits [linux.EV_MAX / 8 + 1]uint8
  116. size := unsafe.Sizeof(bits)
  117. err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
  118. if err != nil {
  119. return nil, err
  120. }
  121. fmt.Printf("size %d, bits: %v\n", size, bits)
  122. result := []SupportedEvent{}
  123. for i := uint(0); i < uint(linux.EV_MAX); i++ {
  124. if (TestBit(bits[0:len(bits)],i)) {
  125. result = append(result, SupportedEvent(uint(i)))
  126. }
  127. }
  128. return result, nil
  129. }
  130. // More Go-like names for the low leve kernel api structs
  131. type InputAbsinfo linux.INPUT_absinfo
  132. type InputEvent linux.INPUT_event
  133. type AbsoluteAxis struct {
  134. Index uint
  135. InputAbsinfo
  136. }
  137. func (ax AbsoluteAxis) Name() string {
  138. return linux.AbsToString(ax.Index)
  139. }
  140. func (ax AbsoluteAxis) String() string {
  141. return fmt.Sprintf("%s %d (min:%d max:%d flat:%d fuzz:%d)",
  142. ax.Name(),
  143. ax.Value,
  144. ax.Minimum,
  145. ax.Maximum,
  146. ax.Flat,
  147. ax.Fuzz)
  148. }
  149. func (ev InputEvent) Time() time.Time {
  150. return time.Unix(ev.Timeval.Tv_sec, ev.Timeval.Tv_usec)
  151. }
  152. func (ev InputEvent) String() string {
  153. return fmt.Sprintf("Event: Time: %s Type: %s, Code: %d, Value:%d",
  154. ev.Time().Format("2006-01-02 15:04:05.000000"),
  155. linux.EvToString(uint(ev.Type)),
  156. ev.Code,
  157. ev.Value)
  158. }
  159. // Read performs a read syscall on the given device
  160. func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  161. fmt.Printf("read: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
  162. read, _, errno := syscall.Syscall(
  163. syscall.SYS_READ,
  164. uintptr(d.Fd()),
  165. uintptr(pointer),
  166. uintptr(size))
  167. d.KeepAlive()
  168. if (errno != 0) {
  169. return read, errno
  170. }
  171. return read, nil
  172. }
  173. // Write performs a write syscall on the given device
  174. func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  175. fmt.Printf("write: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
  176. wrote, _, errno := syscall.Syscall(
  177. syscall.SYS_WRITE,
  178. uintptr(d.Fd()),
  179. uintptr(pointer),
  180. uintptr(size))
  181. d.KeepAlive()
  182. if (errno != 0) {
  183. return wrote, errno
  184. }
  185. return wrote, nil
  186. }
  187. const READ_EVENTS_MAX = 64
  188. func (d * Device) ReadEvents() ([]InputEvent, error) {
  189. var events [READ_EVENTS_MAX]InputEvent
  190. size := unsafe.Sizeof(events)
  191. read, err := d.Read(unsafe.Pointer(&events), size)
  192. if err != nil {
  193. return nil, err
  194. }
  195. len := read / unsafe.Sizeof(events[0])
  196. return events[0:len], nil
  197. }
  198. const WRITE_EVENTS_MAX = 64
  199. func (d * Device) WriteEvents(events []InputEvent) (uint, error) {
  200. size := unsafe.Sizeof(events[0]) * uintptr(len(events))
  201. wrote, err := d.Write(unsafe.Pointer(&events[0]), size)
  202. len := uint(wrote / size)
  203. return len, err
  204. }
  205. func (d * Device) SupportedAxes() ([]AbsoluteAxis, error) {
  206. var abs_feat InputAbsinfo;
  207. var abs_b [linux.ABS_MAX/8 + 1]uint8;
  208. size := unsafe.Sizeof(abs_b)
  209. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_ABS, size), unsafe.Pointer(&abs_b))
  210. if err != nil {
  211. return nil, err
  212. }
  213. result := []AbsoluteAxis{}
  214. fmt.Printf("Supported Absolute axes:\n");
  215. for yalv := uint(0); yalv < linux.ABS_MAX; yalv++ {
  216. if TestBit(abs_b[0:len(abs_b)], uint(yalv)) {
  217. fmt.Printf(" Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
  218. err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
  219. if err != nil {
  220. return result, err
  221. }
  222. axis := AbsoluteAxis{Index: yalv, InputAbsinfo: abs_feat}
  223. result = append(result, axis)
  224. }
  225. }
  226. return result, nil
  227. }
  228. type SupportedKey uint
  229. func (se SupportedKey) Name() string {
  230. return linux.KeyString(uint(se))
  231. }
  232. func (se SupportedKey) String() string {
  233. return se.Name()
  234. }
  235. func (d * Device) SupportedKeys() ([]SupportedKey, error) {
  236. var bits [linux.KEY_MAX / 8 + 1]uint8
  237. size := unsafe.Sizeof(bits)
  238. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_KEY, uintptr(size)), unsafe.Pointer(&bits));
  239. if err != nil {
  240. return nil, err
  241. }
  242. fmt.Printf("size %d, bits: %v\n", size, bits)
  243. result := []SupportedKey{}
  244. for i := uint(0); i < uint(linux.KEY_MAX); i++ {
  245. if (TestBit(bits[0:len(bits)],i)) {
  246. result = append(result, SupportedKey(uint(i)))
  247. }
  248. }
  249. return result, nil
  250. }
  251. type RelativeAxis uint
  252. func (se RelativeAxis) Name() string {
  253. return linux.RelString(uint(se))
  254. }
  255. func (se RelativeAxis) String() string {
  256. return se.Name()
  257. }
  258. func (d * Device) RelativeAxes() ([]RelativeAxis, error) {
  259. var bits [linux.REL_MAX / 8 + 1]uint8
  260. size := unsafe.Sizeof(bits)
  261. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_REL, uintptr(size)), unsafe.Pointer(&bits));
  262. if err != nil {
  263. return nil, err
  264. }
  265. fmt.Printf("size %d, bits: %v\n", size, bits)
  266. result := []RelativeAxis{}
  267. for i := uint(0); i < uint(linux.REL_MAX); i++ {
  268. if (TestBit(bits[0:len(bits)],i)) {
  269. result = append(result, RelativeAxis(uint(i)))
  270. }
  271. }
  272. return result, nil
  273. }
  274. type Manager struct {
  275. Connect chan(*Device)
  276. Disconnect chan(*Device)
  277. Errors chan(error)
  278. Events chan(InputEvent)
  279. Done bool
  280. Devices []*Device
  281. DevicesByName map[string] *Device
  282. DevicesByFd map[int] *Device
  283. fds []syscall.PollFd
  284. }
  285. func NewManager(connect chan(*Device), disconnect chan(*Device), event chan(InputEvent), errors chan(error), done chan (struct{})) * Manager {
  286. manager := &Manager{Connect: connect, Disconnect: disconnect, Errors: errors, Done: false}
  287. manager.Events = event
  288. manager.Devices = []*Device{}
  289. manager.DevicesByName = make(map[string] *Device)
  290. manager.DevicesByFd = make(map[int] *Device)
  291. manager.fds = []syscall.PollFd{}
  292. return manager
  293. }
  294. func (manager *Manager) connectDevice(device * Device) {
  295. manager.DevicesByName[device.FileName] = device
  296. manager.DevicesByFd[int(device.Fd())] = device
  297. manager.Devices = append(manager.Devices, device)
  298. pollfd := syscall.PollFd{Fd: int32(device.Fd()), Events : syscall.POLLIN}
  299. manager.fds = append(manager.fds, pollfd)
  300. manager.Connect <- device
  301. }
  302. func (manager *Manager) disconnectDevice(device * Device) {
  303. delete(manager.DevicesByName, device.FileName)
  304. delete(manager.DevicesByFd, int(device.Fd()))
  305. found := false
  306. var i int
  307. var pollfd syscall.PollFd
  308. for i, pollfd = range manager.fds {
  309. if pollfd.Fd == int32(device.Fd()) {
  310. found = true
  311. break
  312. }
  313. }
  314. if found {
  315. manager.fds = append(manager.fds[:i], manager.fds[(i+1):]...)
  316. manager.Devices = append(manager.Devices[:i], manager.Devices[(i+1):]...)
  317. manager.Disconnect <- device
  318. }
  319. }
  320. func (manager * Manager) ManageNewDevicesOnce() {
  321. names, err := List()
  322. if err != nil {
  323. manager.Errors <- err
  324. } else {
  325. for _, name := range names {
  326. if _, found := manager.DevicesByName[name] ; !found {
  327. device, err := Open(name)
  328. if err == nil {
  329. manager.connectDevice(device)
  330. } else {
  331. manager.Errors <- err
  332. }
  333. }
  334. }
  335. }
  336. }
  337. func (manager *Manager) ReadEventsOnce(device * Device) {
  338. events, err := device.ReadEvents()
  339. if err != nil {
  340. manager.Errors <- err
  341. manager.disconnectDevice(device)
  342. } else {
  343. for _, event := range events {
  344. manager.Events <- event
  345. }
  346. }
  347. }
  348. func (manager *Manager) ManageInputOnce() {
  349. res, err := syscall.Poll(manager.fds, 0)
  350. if err != nil {
  351. manager.Errors <- err
  352. }
  353. if res > 0 {
  354. for _, fd := range manager.fds {
  355. if (fd.Revents & syscall.POLLIN) != 0 {
  356. device, ok := manager.DevicesByFd[int(fd.Fd)]
  357. if ok && device != nil {
  358. manager.ReadEventsOnce(device)
  359. }
  360. }
  361. }
  362. }
  363. }
  364. /*
  365. printf("Supported events:\n");
  366. for (i = 0; i < EV_MAX; i++)
  367. if (TestBit(i, bit[0])) {
  368. }
  369. printf("Testing ... (interrupt to exit)\n");
  370. while (1) {
  371. rd = read(fd, ev, sizeof(struct input_event) * 64);
  372. if (rd < (int) sizeof(struct input_event)) {
  373. printf("yyy\n");
  374. perror("\nevtest: error reading");
  375. return 1;
  376. }
  377. for (i = 0; i < rd / sizeof(struct input_event); i++)
  378. if (ev[i].type == EV_SYN) {
  379. printf("Event: time %ld.%06ld, -------------- %s ------------\n",
  380. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
  381. } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
  382. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
  383. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  384. events[ev[i].type] ? events[ev[i].type] : "?",
  385. ev[i].code,
  386. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  387. ev[i].value);
  388. } else {
  389. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
  390. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  391. events[ev[i].type] ? events[ev[i].type] : "?",
  392. ev[i].code,
  393. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  394. ev[i].value);
  395. }
  396. }
  397. }
  398. */