input_linux.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. *os.File
  16. }
  17. const Directory = "/dev/input"
  18. func (d * Device) KeepAlive() {
  19. runtime.KeepAlive(d.File)
  20. }
  21. func Open(name string) (*Device, error) {
  22. f, err := os.OpenFile(filepath.Join(Directory, name),
  23. syscall.O_ASYNC|syscall.O_NONBLOCK|os.O_RDWR, 0666)
  24. if err != nil {
  25. return nil, err
  26. }
  27. if err = syscall.SetNonblock(int(f.Fd()), true); err != nil {
  28. return nil, err
  29. }
  30. return &Device{File: f}, nil
  31. }
  32. func List() ([]string, error) {
  33. dir, err := os.Open(Directory)
  34. if err != nil {
  35. return nil, err
  36. }
  37. names, err := dir.Readdirnames(-1)
  38. if err != nil {
  39. return names, err
  40. }
  41. results := names[:0]
  42. for _, name := range names {
  43. if strings.HasPrefix(name, "event") {
  44. results = append(results, name)
  45. }
  46. }
  47. return results, nil
  48. }
  49. // Icotl performs an ioctl on the given device
  50. func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
  51. fmt.Printf("ioctl: %d %d %d\n", uintptr(d.Fd()), uintptr(code), uintptr(pointer))
  52. _, _, errno := syscall.Syscall(
  53. syscall.SYS_IOCTL,
  54. uintptr(d.Fd()),
  55. uintptr(code),
  56. uintptr(pointer))
  57. if (errno != 0) {
  58. return errno
  59. }
  60. d.KeepAlive()
  61. return nil
  62. }
  63. func (d * Device) DriverVersion() (int32, error) {
  64. res := int32(0)
  65. data := unsafe.Pointer(&res)
  66. err := d.Ioctl(linux.EVIOCGVERSION, data)
  67. return res, err
  68. }
  69. const NAME_MAX = 256
  70. func (d * Device) Name() (string, error) {
  71. buffer := [NAME_MAX]byte{}
  72. err := d.Ioctl(linux.EVIOCGNAME(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  73. return string(buffer[0:len(buffer)]), err
  74. }
  75. func (d * Device) Id() (linux.INPUT_id, error) {
  76. var result linux.INPUT_id
  77. err := d.Ioctl(linux.EVIOCGID, unsafe.Pointer(&result))
  78. return result, err
  79. }
  80. // The Linux developers thought it was a great idea a to use an array of
  81. // unsigned longs for the bit flags of input devices. Of course, the length
  82. // of an unsigned long is platform dependent which then entails all sorts of
  83. // gymnastics to extract the bits from the array.
  84. // To avoid this, we use a byte array instead, which might lessen performance,
  85. // but is much easier to use.
  86. const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))
  87. const BITS_PER_LONG = SIZEOF_LONG * 8
  88. func BitsToLong(bits uint) uint {
  89. return ((bits) + (8 * SIZEOF_LONG) - 1) / (8 * SIZEOF_LONG)
  90. }
  91. const TOPOLOGY_MAX = 256
  92. func (d * Device) Topology() (string, error) {
  93. buffer := [TOPOLOGY_MAX]byte{}
  94. err := d.Ioctl(linux.EVIOCGPHYS(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  95. return string(buffer[0:len(buffer)]), err
  96. }
  97. func TestBit(array []uint8, bit uint) bool {
  98. elem := uint(array[ bit / 8 ])
  99. flag := uint(1) << uint(bit % 8)
  100. return (elem & flag ) != 0
  101. }
  102. type SupportedEvent uint
  103. func (se SupportedEvent) Name() string {
  104. return linux.EvToString(uint(se))
  105. }
  106. func (se SupportedEvent) String() string {
  107. return se.Name()
  108. }
  109. func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
  110. var bits [linux.EV_MAX / 8 + 1]uint8
  111. size := unsafe.Sizeof(bits)
  112. err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
  113. if err != nil {
  114. return nil, err
  115. }
  116. fmt.Printf("size %d, bits: %v\n", size, bits)
  117. result := []SupportedEvent{}
  118. for i := uint(0); i < uint(linux.EV_MAX); i++ {
  119. if (TestBit(bits[0:len(bits)],i)) {
  120. result = append(result, SupportedEvent(uint(i)))
  121. }
  122. }
  123. return result, nil
  124. }
  125. // More Go-like names for the low leve kernel api structs
  126. type InputAbsinfo linux.INPUT_absinfo
  127. type InputEvent linux.INPUT_event
  128. type AbsoluteAxis struct {
  129. Index uint
  130. InputAbsinfo
  131. }
  132. func (ax AbsoluteAxis) Name() string {
  133. return linux.AbsToString(ax.Index)
  134. }
  135. func (ax AbsoluteAxis) String() string {
  136. return fmt.Sprintf("%s %d (min:%d max:%d flat:%d fuzz:%d)",
  137. ax.Name(),
  138. ax.Value,
  139. ax.Minimum,
  140. ax.Maximum,
  141. ax.Flat,
  142. ax.Fuzz)
  143. }
  144. func (ev InputEvent) Time() time.Time {
  145. return time.Unix(ev.Timeval.Tv_sec, ev.Timeval.Tv_usec)
  146. }
  147. func (ev InputEvent) String() string {
  148. return fmt.Sprintf("Event: Time: %s Type: %s, Code: %d, Value:%d",
  149. ev.Time().Format("2006-01-02 15:04:05.000000"),
  150. linux.EvToString(uint(ev.Type)),
  151. ev.Code,
  152. ev.Value)
  153. }
  154. // Read performs a read syscall on the given device
  155. func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  156. fmt.Printf("read: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
  157. read, _, errno := syscall.Syscall(
  158. syscall.SYS_READ,
  159. uintptr(d.Fd()),
  160. uintptr(pointer),
  161. uintptr(size))
  162. d.KeepAlive()
  163. if (errno != 0) {
  164. return read, errno
  165. }
  166. return read, nil
  167. }
  168. // Write performs a write syscall on the given device
  169. func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  170. fmt.Printf("write: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
  171. wrote, _, errno := syscall.Syscall(
  172. syscall.SYS_WRITE,
  173. uintptr(d.Fd()),
  174. uintptr(pointer),
  175. uintptr(size))
  176. d.KeepAlive()
  177. if (errno != 0) {
  178. return wrote, errno
  179. }
  180. return wrote, nil
  181. }
  182. const READ_EVENTS_MAX = 64
  183. func (d * Device) ReadEvents() ([]InputEvent, error) {
  184. var events [READ_EVENTS_MAX]InputEvent
  185. size := unsafe.Sizeof(events)
  186. read, err := d.Read(unsafe.Pointer(&events), size)
  187. if err != nil {
  188. return nil, err
  189. }
  190. len := read / unsafe.Sizeof(events[0])
  191. return events[0:len], nil
  192. }
  193. const WRITE_EVENTS_MAX = 64
  194. func (d * Device) WriteEvents(events []InputEvent) (uint, error) {
  195. size := unsafe.Sizeof(events[0]) * uintptr(len(events))
  196. wrote, err := d.Write(unsafe.Pointer(&events[0]), size)
  197. len := uint(wrote / size)
  198. return len, err
  199. }
  200. func (d * Device) SupportedAxes() ([]AbsoluteAxis, error) {
  201. var abs_feat InputAbsinfo;
  202. var abs_b [linux.ABS_MAX/8 + 1]uint8;
  203. size := unsafe.Sizeof(abs_b)
  204. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_ABS, size), unsafe.Pointer(&abs_b))
  205. if err != nil {
  206. return nil, err
  207. }
  208. result := []AbsoluteAxis{}
  209. fmt.Printf("Supported Absolute axes:\n");
  210. for yalv := uint(0); yalv < linux.ABS_MAX; yalv++ {
  211. if TestBit(abs_b[0:len(abs_b)], uint(yalv)) {
  212. fmt.Printf(" Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
  213. err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
  214. if err != nil {
  215. return result, err
  216. }
  217. axis := AbsoluteAxis{Index: yalv, InputAbsinfo: abs_feat}
  218. result = append(result, axis)
  219. }
  220. }
  221. return result, nil
  222. }
  223. type SupportedKey uint
  224. func (se SupportedKey) Name() string {
  225. return linux.KeyString(uint(se))
  226. }
  227. func (se SupportedKey) String() string {
  228. return se.Name()
  229. }
  230. func (d * Device) SupportedKeys() ([]SupportedKey, error) {
  231. var bits [linux.KEY_MAX / 8 + 1]uint8
  232. size := unsafe.Sizeof(bits)
  233. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_KEY, uintptr(size)), unsafe.Pointer(&bits));
  234. if err != nil {
  235. return nil, err
  236. }
  237. fmt.Printf("size %d, bits: %v\n", size, bits)
  238. result := []SupportedKey{}
  239. for i := uint(0); i < uint(linux.KEY_MAX); i++ {
  240. if (TestBit(bits[0:len(bits)],i)) {
  241. result = append(result, SupportedKey(uint(i)))
  242. }
  243. }
  244. return result, nil
  245. }
  246. type RelativeAxis uint
  247. func (se RelativeAxis) Name() string {
  248. return linux.RelString(uint(se))
  249. }
  250. func (se RelativeAxis) String() string {
  251. return se.Name()
  252. }
  253. func (d * Device) RelativeAxes() ([]RelativeAxis, error) {
  254. var bits [linux.REL_MAX / 8 + 1]uint8
  255. size := unsafe.Sizeof(bits)
  256. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_REL, uintptr(size)), unsafe.Pointer(&bits));
  257. if err != nil {
  258. return nil, err
  259. }
  260. fmt.Printf("size %d, bits: %v\n", size, bits)
  261. result := []RelativeAxis{}
  262. for i := uint(0); i < uint(linux.REL_MAX); i++ {
  263. if (TestBit(bits[0:len(bits)],i)) {
  264. result = append(result, RelativeAxis(uint(i)))
  265. }
  266. }
  267. return result, nil
  268. }
  269. /*
  270. printf("Supported events:\n");
  271. for (i = 0; i < EV_MAX; i++)
  272. if (TestBit(i, bit[0])) {
  273. }
  274. printf("Testing ... (interrupt to exit)\n");
  275. while (1) {
  276. rd = read(fd, ev, sizeof(struct input_event) * 64);
  277. if (rd < (int) sizeof(struct input_event)) {
  278. printf("yyy\n");
  279. perror("\nevtest: error reading");
  280. return 1;
  281. }
  282. for (i = 0; i < rd / sizeof(struct input_event); i++)
  283. if (ev[i].type == EV_SYN) {
  284. printf("Event: time %ld.%06ld, -------------- %s ------------\n",
  285. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
  286. } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
  287. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
  288. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  289. events[ev[i].type] ? events[ev[i].type] : "?",
  290. ev[i].code,
  291. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  292. ev[i].value);
  293. } else {
  294. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
  295. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  296. events[ev[i].type] ? events[ev[i].type] : "?",
  297. ev[i].code,
  298. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  299. ev[i].value);
  300. }
  301. }
  302. }
  303. */