Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.28 KB | None | 0 0
  1. package main
  2.  
  3. // #cgo pkg-config: libinput
  4. /*
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <libinput.h>
  8. #include <poll.h>
  9. #include <unistd.h>
  10.  
  11. int open_restricted(const char *path, int flags, void *user_data)
  12. {
  13. int fd = open(path, flags);
  14. return fd < 0 ? -errno : fd;
  15. }
  16.  
  17. void close_restricted(int fd, void *user_data)
  18. {
  19. close(fd);
  20. }
  21.  
  22. const struct libinput_interface iface = {
  23. .open_restricted = open_restricted,
  24. .close_restricted = close_restricted,
  25. };
  26. */
  27. import "C"
  28.  
  29. import (
  30. "fmt"
  31. "log"
  32. "math"
  33. "os/exec"
  34. "unsafe"
  35. )
  36.  
  37. func main() {
  38. li := C.libinput_path_create_context(&C.iface, nil)
  39.  
  40. devicePath := C.CString("/dev/input/event4")
  41. C.libinput_path_add_device(li, devicePath)
  42.  
  43. if handleAndProcessEvents(li, nil) == 0 {
  44. log.Fatal("Expected device added events on startup but got none.")
  45. }
  46.  
  47. // Create a channel to receive events from the main loop.
  48. eventChan := make(chan GestureEvent)
  49. finished := make(chan bool)
  50. go mainLoop(li, eventChan, finished)
  51. processingLoop(eventChan)
  52.  
  53. // Wait for finished signal to arrive, then close the channel and clean up
  54. // related resources.
  55. <-finished
  56. close(finished)
  57. close(eventChan)
  58.  
  59. C.libinput_unref(li)
  60. C.free(unsafe.Pointer(devicePath))
  61.  
  62. fmt.Println("Hello")
  63. }
  64.  
  65. func mainLoop(li *C.struct_libinput, eventChan chan GestureEvent, finished chan bool) {
  66. fds := C.struct_pollfd{
  67. fd: C.libinput_get_fd(li),
  68. events: C.POLLIN,
  69. revents: 0,
  70. }
  71.  
  72. for {
  73. if C.poll(&fds, 1, -1) > -1 {
  74. handleAndProcessEvents(li, eventChan)
  75. }
  76. }
  77.  
  78. finished <- true
  79. }
  80.  
  81. func processingLoop(eventChan chan GestureEvent) {
  82. const minSamples = 3
  83.  
  84. var currentSwipe []GestureEvent
  85. isCurrentSwipeProcessed := false
  86.  
  87. for {
  88. event := <-eventChan
  89.  
  90. switch event.EventType {
  91. case C.LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
  92. currentSwipe = nil
  93. case C.LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
  94. currentSwipe = append(currentSwipe, event)
  95. if len(currentSwipe) >= minSamples && !isCurrentSwipeProcessed {
  96. direction := getSwipeDirection(currentSwipe)
  97. invokeAction(event.FingerCount, direction)
  98. isCurrentSwipeProcessed = true
  99. fmt.Printf("Processing %d events, direction %s\n", len(currentSwipe), direction)
  100. }
  101. case C.LIBINPUT_EVENT_GESTURE_SWIPE_END:
  102. isCurrentSwipeProcessed = false
  103. }
  104. }
  105. }
  106.  
  107. func invokeAction(numFingers int, direction SwipeDirection) {
  108. if numFingers == 3 && direction == SwipeDirectionTop {
  109. switch direction {
  110. case SwipeDirectionTop:
  111. cmd := exec.Command("xdotool", "key", "Super+W")
  112. cmd.Start()
  113. case SwipeDirectionBottom:
  114. cmd := exec.Command("xdotool", "key", "Super+W")
  115. cmd.Start()
  116. }
  117. }
  118.  
  119. if numFingers == 4 {
  120. switch direction {
  121. case SwipeDirectionLeft:
  122. cmd := exec.Command("xdotool", "key", "Ctrl+Alt+Right")
  123. cmd.Start()
  124. case SwipeDirectionRight:
  125. cmd := exec.Command("xdotool", "key", "Ctrl+Alt+Left")
  126. cmd.Start()
  127. }
  128. }
  129. }
  130.  
  131. func getSwipeDirection(swipe []GestureEvent) SwipeDirection {
  132. xVector, yVector := float64(0), float64(0)
  133.  
  134. for _, sample := range swipe {
  135. xVector = xVector + sample.Dx
  136. yVector = yVector + sample.Dy
  137. }
  138.  
  139. angle := math.Atan(yVector/xVector) * 180 / math.Pi
  140. if xVector > 0 {
  141. if angle > -45 && angle < 45 {
  142. return SwipeDirectionRight
  143. } else if angle < -45 {
  144. return SwipeDirectionTop
  145. } else {
  146. return SwipeDirectionBottom
  147. }
  148. } else {
  149. if angle > -45 && angle < 45 {
  150. return SwipeDirectionLeft
  151. } else if angle < -45 {
  152. return SwipeDirectionBottom
  153. } else {
  154. return SwipeDirectionTop
  155. }
  156. }
  157. }
  158.  
  159. func handleAndProcessEvents(li *C.struct_libinput, eventChan chan GestureEvent) (numEvents int) {
  160. numEvents = 0
  161.  
  162. C.libinput_dispatch(li)
  163. for {
  164. event := C.libinput_get_event(li)
  165. if event == nil {
  166. break
  167. }
  168.  
  169. switch eventType := C.libinput_event_get_type(event); eventType {
  170. case C.LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
  171. gestureEvent := C.libinput_event_get_gesture_event(event)
  172. eventChan <- GestureEvent{
  173. EventType: eventType,
  174. FingerCount: int(C.libinput_event_gesture_get_finger_count(gestureEvent)),
  175. }
  176. case C.LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
  177. gestureEvent := C.libinput_event_get_gesture_event(event)
  178. eventChan <- GestureEvent{
  179. EventType: eventType,
  180. FingerCount: int(C.libinput_event_gesture_get_finger_count(gestureEvent)),
  181. Dx: float64(C.libinput_event_gesture_get_dx(gestureEvent)),
  182. Dy: float64(C.libinput_event_gesture_get_dy(gestureEvent)),
  183. }
  184. case C.LIBINPUT_EVENT_GESTURE_SWIPE_END:
  185. gestureEvent := C.libinput_event_get_gesture_event(event)
  186. eventChan <- GestureEvent{
  187. EventType: eventType,
  188. FingerCount: int(C.libinput_event_gesture_get_finger_count(gestureEvent)),
  189. }
  190. }
  191.  
  192. C.libinput_event_destroy(event)
  193. C.libinput_dispatch(li)
  194.  
  195. numEvents = numEvents + 1
  196. }
  197.  
  198. return numEvents
  199. }
  200.  
  201. // GestureEvent contains information about a gesture.
  202. type GestureEvent struct {
  203. EventType uint32
  204. FingerCount int
  205. Dx float64
  206. Dy float64
  207. }
  208.  
  209. // SwipeDirection denotes the direction of the swipe.
  210. type SwipeDirection int
  211.  
  212. const (
  213. // SwipeDirectionTop denotes a swipe to the top.
  214. SwipeDirectionTop SwipeDirection = iota
  215. // SwipeDirectionRight denotes a swipe to the right.
  216. SwipeDirectionRight SwipeDirection = iota
  217. // SwipeDirectionBottom denotes a swipe to the bottom.
  218. SwipeDirectionBottom SwipeDirection = iota
  219. // SwipeDirectionLeft denotes a swipe to the left.
  220. SwipeDirectionLeft SwipeDirection = iota
  221. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement