github.com/rajveermalviya/gamen@v0.1.2-0.20220930195403-9be15877c1aa/internal/xcb/device.go (about) 1 //go:build linux && !android 2 3 package xcb 4 5 /* 6 7 #include <stdlib.h> 8 #include <xcb/xcb.h> 9 #include <xcb/xinput.h> 10 11 */ 12 import "C" 13 14 import ( 15 "errors" 16 "unsafe" 17 ) 18 19 type scrollAxis struct { 20 index C.uint16_t 21 increment float64 22 position float64 23 } 24 25 type scrollingDevice struct { 26 horizontalScroll scrollAxis 27 verticalScroll scrollAxis 28 } 29 30 func (d *Display) xiSetupScrollingDevices(id C.xcb_input_device_id_t) error { 31 reply := d.l.xcb_input_xi_query_device_reply(d.xcbConn, id) 32 if reply == nil { 33 return errors.New("failed to setup xinput scrolling devices") 34 } 35 defer C.free(unsafe.Pointer(reply)) 36 37 for it := d.l.xcb_input_xi_query_device_infos_iterator(reply); it.rem > 0; d.l.xcb_input_xi_device_info_next(&it) { 38 deviceInfo := it.data 39 40 if deviceInfo._type != C.XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER { 41 continue 42 } 43 44 var dev scrollingDevice 45 46 for it := d.l.xcb_input_xi_device_info_classes_iterator(deviceInfo); it.rem != 0; d.l.xcb_input_device_class_next(&it) { 47 classInfo := it.data 48 switch classInfo._type { 49 case C.XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL: 50 scrollClassInfo := (*C.xcb_input_scroll_class_t)(unsafe.Pointer(classInfo)) 51 52 switch scrollClassInfo.scroll_type { 53 case C.XCB_INPUT_SCROLL_TYPE_VERTICAL: 54 dev.verticalScroll.index = scrollClassInfo.number 55 dev.verticalScroll.increment = fixed3232ToFloat64(scrollClassInfo.increment) 56 57 case C.XCB_INPUT_SCROLL_TYPE_HORIZONTAL: 58 dev.horizontalScroll.index = scrollClassInfo.number 59 dev.horizontalScroll.increment = fixed3232ToFloat64(scrollClassInfo.increment) 60 } 61 62 case C.XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR: 63 vci := (*C.xcb_input_valuator_class_t)(unsafe.Pointer(classInfo)) 64 65 switch vci.label { 66 case d.relHorizScroll, d.relHorizWheel: 67 dev.horizontalScroll.position = fixed3232ToFloat64(vci.value) 68 case d.relVertScroll, d.relVertWheel: 69 dev.verticalScroll.position = fixed3232ToFloat64(vci.value) 70 } 71 } 72 } 73 74 d.scrollingDevices[deviceInfo.deviceid] = dev 75 } 76 77 return nil 78 } 79 80 func (d *Display) resetScrollPosition(id C.xcb_input_device_id_t) { 81 reply := d.l.xcb_input_xi_query_device_reply(d.xcbConn, id) 82 if reply == nil { 83 return 84 } 85 defer C.free(unsafe.Pointer(reply)) 86 87 for it := d.l.xcb_input_xi_query_device_infos_iterator(reply); it.rem > 0; d.l.xcb_input_xi_device_info_next(&it) { 88 deviceInfo := it.data 89 90 if deviceInfo._type != C.XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER { 91 continue 92 } 93 94 dev, ok := d.scrollingDevices[deviceInfo.deviceid] 95 if !ok { 96 continue 97 } 98 99 for it := d.l.xcb_input_xi_device_info_classes_iterator(deviceInfo); it.rem != 0; d.l.xcb_input_device_class_next(&it) { 100 classInfo := it.data 101 if classInfo._type != C.XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR { 102 continue 103 } 104 105 vci := (*C.xcb_input_valuator_class_t)(unsafe.Pointer(classInfo)) 106 switch vci.label { 107 case d.relHorizScroll, d.relHorizWheel: 108 dev.horizontalScroll.position = fixed3232ToFloat64(vci.value) 109 110 case d.relVertScroll, d.relVertWheel: 111 dev.verticalScroll.position = fixed3232ToFloat64(vci.value) 112 } 113 } 114 115 d.scrollingDevices[deviceInfo.deviceid] = dev 116 } 117 }