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  }