input_linux.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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 "os"
  6. import "unsafe"
  7. import syscall "golang.org/x/sys/unix"
  8. import "fmt"
  9. import "path/filepath"
  10. // Device models an input device
  11. type Device struct {
  12. *os.File
  13. }
  14. const Directory = "/dev/input"
  15. func Open(name string) (*Device, error) {
  16. f, err := os.OpenFile(filepath.Join(Directory, name),
  17. syscall.O_ASYNC|syscall.O_NONBLOCK|os.O_RDWR, 0666)
  18. if err != nil {
  19. return nil, err
  20. }
  21. return &Device{File: f}, nil
  22. }
  23. func List() ([]string, error) {
  24. dir, err := os.Open(Directory)
  25. if err != nil {
  26. return nil, err
  27. }
  28. return dir.Readdirnames(-1)
  29. }
  30. // Icotl performs an ioctl on the given device
  31. func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
  32. fmt.Printf("ioctl: %d %d %d\n", uintptr(d.Fd()), uintptr(code), uintptr(pointer))
  33. _, _, errno := syscall.Syscall(
  34. syscall.SYS_IOCTL,
  35. uintptr(d.Fd()),
  36. uintptr(code),
  37. uintptr(pointer))
  38. if (errno != 0) {
  39. return errno
  40. }
  41. return nil
  42. }
  43. func (d * Device) DriverVersion() (int32, error) {
  44. res := int32(0)
  45. data := unsafe.Pointer(&res)
  46. err := d.Ioctl(linux.EVIOCGVERSION, data)
  47. return res, err
  48. }
  49. func (d * Device) Name() (string, error) {
  50. buffer := [256]byte{}
  51. err := d.Ioctl(linux.EVIOCGNAME(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  52. return string(buffer[0:len(buffer)]), err
  53. }
  54. func (d * Device) Id() (linux.INPUT_id, error) {
  55. var result linux.INPUT_id
  56. err := d.Ioctl(linux.EVIOCGID, unsafe.Pointer(&result))
  57. return result, err
  58. }
  59. // The Linux developers thought it was a great idea a to use an array of
  60. // unsigned longs for the bit flags of input devices. Of course, the length
  61. // of an unsigned long is platform dependent which then entails all sorts of
  62. // gymnastics to extract the bits from the array...
  63. const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))
  64. const BITS_PER_LONG = SIZEOF_LONG * 8
  65. func BitsToLong(bits uint) uint {
  66. return ((bits) + (8 * SIZEOF_LONG) - 1) / (8 * SIZEOF_LONG)
  67. }
  68. func (d * Device) Topology() (string, error) {
  69. buffer := [256]byte{}
  70. err := d.Ioctl(linux.EVIOCGPHYS(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  71. return string(buffer[0:len(buffer)]), err
  72. }
  73. func TestBit(array []uint8, bit uint) bool {
  74. elem := uint(array[ bit / 8 ])
  75. flag := uint(1) << uint(bit % 8)
  76. return (elem & flag ) != 0
  77. }
  78. type SupportedEvent uint
  79. func (se SupportedEvent) Name() string {
  80. return linux.EvToString(uint(se))
  81. }
  82. func (se SupportedEvent) String() string {
  83. return se.Name()
  84. }
  85. func (d * Device) SupportedEvents() ([]SupportedEvent, error) {
  86. var bits [linux.EV_MAX / 8 + 1]uint8
  87. size := unsafe.Sizeof(bits)
  88. err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
  89. if err != nil {
  90. return nil, err
  91. }
  92. fmt.Printf("size %d, bits: %v\n", size, bits)
  93. result := []SupportedEvent{}
  94. for i := uint(0); i < uint(linux.EV_MAX); i++ {
  95. if (TestBit(bits[0:len(bits)],i)) {
  96. result = append(result, SupportedEvent(uint(i)))
  97. }
  98. }
  99. return result, nil
  100. }
  101. // More Go-like names for the low leve kernel api structs
  102. type InputAbsinfo linux.INPUT_absinfo
  103. type InputEvent linux.INPUT_event
  104. type AbsoluteAxis struct {
  105. Index uint
  106. InputAbsinfo
  107. }
  108. func (ax AbsoluteAxis) Name() string {
  109. return linux.AbsToString(ax.Index)
  110. }
  111. func (ax AbsoluteAxis) String() string {
  112. return fmt.Sprintf("%s %d (min:%d max:%d flat:%d fuzz:%d)",
  113. ax.Name(),
  114. ax.Value,
  115. ax.Minimum,
  116. ax.Maximum,
  117. ax.Flat,
  118. ax.Fuzz)
  119. }
  120. func (ev InputEvent) String() string {
  121. return fmt.Sprintf("Event: Time: %d Type: %s, Code: %d, Value:%d",
  122. ev.Time,
  123. linux.EvToString(uint(ev.Type)),
  124. ev.Code,
  125. ev.Value)
  126. }
  127. // Read performs a read syscall on the given device
  128. func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
  129. fmt.Printf("read: %d %d %d\n", uintptr(d.Fd()), uintptr(pointer), uintptr(size))
  130. read, _, errno := syscall.Syscall(
  131. syscall.SYS_READ,
  132. uintptr(d.Fd()),
  133. uintptr(pointer),
  134. uintptr(size))
  135. if (errno != 0) {
  136. return read, errno
  137. }
  138. return read, nil
  139. }
  140. const READ_EVENTS_MAX = 64
  141. func (d * Device) ReadEvents() ([]InputEvent, error) {
  142. var events [READ_EVENTS_MAX]InputEvent
  143. size := unsafe.Sizeof(events)
  144. read, err := d.Read(unsafe.Pointer(&events), size)
  145. if err != nil {
  146. return nil, err
  147. }
  148. len := read / unsafe.Sizeof(events[0])
  149. return events[0:len], nil
  150. }
  151. func (d * Device) SupportedAxes() ([]AbsoluteAxis, error) {
  152. var abs_feat InputAbsinfo;
  153. var abs_b [linux.ABS_MAX/8 + 1]uint8;
  154. size := unsafe.Sizeof(abs_b)
  155. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_ABS, size), unsafe.Pointer(&abs_b))
  156. if err != nil {
  157. return nil, err
  158. }
  159. result := []AbsoluteAxis{}
  160. fmt.Printf("Supported Absolute axes:\n");
  161. for yalv := uint(0); yalv < linux.ABS_MAX; yalv++ {
  162. if TestBit(abs_b[0:len(abs_b)], uint(yalv)) {
  163. fmt.Printf(" Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
  164. err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
  165. if err != nil {
  166. return result, err
  167. }
  168. axis := AbsoluteAxis{Index: yalv, InputAbsinfo: abs_feat}
  169. result = append(result, axis)
  170. }
  171. }
  172. return result, nil
  173. }
  174. /*
  175. printf("Supported events:\n");
  176. for (i = 0; i < EV_MAX; i++)
  177. if (TestBit(i, bit[0])) {
  178. }
  179. printf("Testing ... (interrupt to exit)\n");
  180. while (1) {
  181. rd = read(fd, ev, sizeof(struct input_event) * 64);
  182. if (rd < (int) sizeof(struct input_event)) {
  183. printf("yyy\n");
  184. perror("\nevtest: error reading");
  185. return 1;
  186. }
  187. for (i = 0; i < rd / sizeof(struct input_event); i++)
  188. if (ev[i].type == EV_SYN) {
  189. printf("Event: time %ld.%06ld, -------------- %s ------------\n",
  190. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
  191. } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
  192. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
  193. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  194. events[ev[i].type] ? events[ev[i].type] : "?",
  195. ev[i].code,
  196. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  197. ev[i].value);
  198. } else {
  199. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
  200. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  201. events[ev[i].type] ? events[ev[i].type] : "?",
  202. ev[i].code,
  203. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  204. ev[i].value);
  205. }
  206. }
  207. }
  208. */