input_linux.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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"
  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), os.O_RDWR, 0666)
  17. if err != nil {
  18. return nil, err
  19. }
  20. return &Device{File: f}, nil
  21. }
  22. func List() ([]string, error) {
  23. dir, err := os.Open(Directory)
  24. if err != nil {
  25. return nil, err
  26. }
  27. return dir.Readdirnames(-1)
  28. }
  29. // Icotl performs an ioctl on the given de
  30. func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
  31. fmt.Printf("ioctl: %d %d %d\n", uintptr(d.Fd()), uintptr(code), uintptr(pointer))
  32. _, _, errno := syscall.Syscall(
  33. syscall.SYS_IOCTL,
  34. uintptr(d.Fd()),
  35. uintptr(code),
  36. uintptr(pointer))
  37. if (errno != 0) {
  38. return errno
  39. }
  40. return nil
  41. }
  42. func (d * Device) DriverVersion() (int32, error) {
  43. res := int32(0)
  44. data := unsafe.Pointer(&res)
  45. err := d.Ioctl(linux.EVIOCGVERSION, data)
  46. return res, err
  47. }
  48. func (d * Device) Name() (string, error) {
  49. buffer := [256]byte{}
  50. err := d.Ioctl(linux.EVIOCGNAME(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  51. return string(buffer[0:len(buffer)]), err
  52. }
  53. func (d * Device) Id() (linux.INPUT_id, error) {
  54. var result linux.INPUT_id
  55. err := d.Ioctl(linux.EVIOCGID, unsafe.Pointer(&result))
  56. return result, err
  57. }
  58. // The Linux developers thought it was a great idea a to use an array of
  59. // unsigned longs for the bit flags of input devices. Of course, the length
  60. // of an unsigned long is platform dependent which then entails all sorts of
  61. // gymnastics to extract the bits from the array...
  62. const SIZEOF_LONG = uint(unsafe.Sizeof(*((*linux.UnsignedLong)(nil))))
  63. const BITS_PER_LONG = SIZEOF_LONG * 8
  64. func BitsToLong(bits uint) uint {
  65. return ((bits) + (8 * SIZEOF_LONG) - 1) / (8 * SIZEOF_LONG)
  66. }
  67. func (d * Device) Topology() (string, error) {
  68. buffer := [256]byte{}
  69. err := d.Ioctl(linux.EVIOCGPHYS(uintptr(len(buffer))), unsafe.Pointer(&buffer))
  70. return string(buffer[0:len(buffer)]), err
  71. }
  72. func TestBit(array []uint8, bit uint) bool {
  73. elem := uint(array[ bit / 8 ])
  74. flag := uint(1) << uint(bit % 8)
  75. return (elem & flag ) != 0
  76. }
  77. func (d * Device) SupportedEvents() ([]uint, error) {
  78. var bits [linux.EV_MAX / 8 + 1]uint8
  79. size := unsafe.Sizeof(bits)
  80. err := d.Ioctl(linux.EVIOCGBIT(0, uintptr(size)), unsafe.Pointer(&bits));
  81. if err != nil {
  82. return nil, err
  83. }
  84. fmt.Printf("size %d, bits: %v\n", size, bits)
  85. result := []uint{}
  86. for i := uint(0); i < uint(linux.EV_MAX); i++ {
  87. if (TestBit(bits[0:len(bits)],i)) {
  88. result = append(result, uint(i))
  89. }
  90. }
  91. return result, nil
  92. }
  93. type InputAbsinfo struct {
  94. Value int32
  95. Minimum int32
  96. Maximum int32
  97. Fuzz int32
  98. Flat int32
  99. }
  100. type AbsoluteAxis struct {
  101. Index uint
  102. InputAbsinfo
  103. }
  104. func (d * Device) SupportedAxes() (error) {
  105. var abs_feat InputAbsinfo;
  106. var abs_b [linux.ABS_MAX/8 + 1]uint8;
  107. size := unsafe.Sizeof(abs_b)
  108. err := d.Ioctl(linux.EVIOCGBIT(linux.EV_ABS, size), unsafe.Pointer(&abs_b))
  109. if err != nil {
  110. return err
  111. }
  112. fmt.Printf("Supported Absolute axes:\n");
  113. for yalv := uint(0); yalv < linux.ABS_MAX; yalv++ {
  114. if TestBit(abs_b[0:len(abs_b)], uint(yalv)) {
  115. fmt.Printf(" Absolute axis 0x%02x %s", yalv, linux.AbsToString(yalv))
  116. err = d.Ioctl(linux.EVIOCGABS(uint32(yalv)), unsafe.Pointer(&abs_feat))
  117. if err != nil {
  118. return err
  119. }
  120. fmt.Printf("%d (min:%d max:%d flat:%d fuzz:%d)\n",
  121. abs_feat.Value,
  122. abs_feat.Minimum,
  123. abs_feat.Maximum,
  124. abs_feat.Flat,
  125. abs_feat.Fuzz);
  126. }
  127. }
  128. return nil
  129. }
  130. /*
  131. printf("Supported events:\n");
  132. for (i = 0; i < EV_MAX; i++)
  133. if (TestBit(i, bit[0])) {
  134. }
  135. printf("Testing ... (interrupt to exit)\n");
  136. while (1) {
  137. rd = read(fd, ev, sizeof(struct input_event) * 64);
  138. if (rd < (int) sizeof(struct input_event)) {
  139. printf("yyy\n");
  140. perror("\nevtest: error reading");
  141. return 1;
  142. }
  143. for (i = 0; i < rd / sizeof(struct input_event); i++)
  144. if (ev[i].type == EV_SYN) {
  145. printf("Event: time %ld.%06ld, -------------- %s ------------\n",
  146. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
  147. } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
  148. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
  149. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  150. events[ev[i].type] ? events[ev[i].type] : "?",
  151. ev[i].code,
  152. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  153. ev[i].value);
  154. } else {
  155. printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
  156. ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
  157. events[ev[i].type] ? events[ev[i].type] : "?",
  158. ev[i].code,
  159. names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
  160. ev[i].value);
  161. }
  162. }
  163. }
  164. */