@ -279,10 +279,17 @@ static bool should_reset_value120_accumulators(int32_t current, int32_t last) {
static void update_value120_accumulators ( struct wlr_seat_client * client ,
static void update_value120_accumulators ( struct wlr_seat_client * client ,
enum wlr_axis_orientation orientation ,
enum wlr_axis_orientation orientation ,
double value , int32_t value_discrete ) {
double value , int32_t value_discrete ,
double * low_res_value , int32_t * low_res_value_discrete ) {
if ( value_discrete = = 0 ) {
// Continuous scrolling has no effect on accumulators
return ;
}
int32_t * acc_discrete = & client - > value120 . acc_discrete [ orientation ] ;
int32_t * acc_discrete = & client - > value120 . acc_discrete [ orientation ] ;
int32_t * last_discrete = & client - > value120 . last_discrete [ orientation ] ;
int32_t * last_discrete = & client - > value120 . last_discrete [ orientation ] ;
double * acc_axis = & client - > value120 . acc_axis [ orientation ] ;
double * acc_axis = & client - > value120 . acc_axis [ orientation ] ;
if ( should_reset_value120_accumulators ( value_discrete , * last_discrete ) ) {
if ( should_reset_value120_accumulators ( value_discrete , * last_discrete ) ) {
* acc_discrete = 0 ;
* acc_discrete = 0 ;
* acc_axis = 0 ;
* acc_axis = 0 ;
@ -290,33 +297,17 @@ static void update_value120_accumulators(struct wlr_seat_client *client,
* acc_discrete + = value_discrete ;
* acc_discrete + = value_discrete ;
* last_discrete = value_discrete ;
* last_discrete = value_discrete ;
* acc_axis + = value ;
* acc_axis + = value ;
}
static void send_axis_discrete ( struct wlr_seat_client * client ,
// Compute low resolution event values for older clients and reset
struct wl_resource * resource , uint32_t time ,
// the accumulators if needed
enum wlr_axis_orientation orientation , double value ,
* low_res_value_discrete = * acc_discrete / WLR_POINTER_AXIS_DISCRETE_STEP ;
int32_t value_discrete ) {
if ( * low_res_value_discrete = = 0 ) {
int32_t * acc_discrete = & client - > value120 . acc_discrete [ orientation ] ;
* low_res_value = 0 ;
double * acc_axis = & client - > value120 . acc_axis [ orientation ] ;
} else {
* acc_discrete - = * low_res_value_discrete * WLR_POINTER_AXIS_DISCRETE_STEP ;
if ( abs ( * acc_discrete ) < WLR_POINTER_AXIS_DISCRETE_STEP ) {
* low_res_value = * acc_axis ;
return ;
* acc_axis = 0 ;
}
}
wl_pointer_send_axis_discrete ( resource , orientation ,
* acc_discrete / WLR_POINTER_AXIS_DISCRETE_STEP ) ;
wl_pointer_send_axis ( resource , time , orientation ,
wl_fixed_from_double ( * acc_axis ) ) ;
* acc_discrete % = WLR_POINTER_AXIS_DISCRETE_STEP ;
* acc_axis = 0 ;
}
static void send_axis_value120 ( struct wl_resource * resource , uint32_t time ,
enum wlr_axis_orientation orientation , double value ,
int32_t value_discrete ) {
wl_pointer_send_axis_value120 ( resource , orientation , value_discrete ) ;
wl_pointer_send_axis ( resource , time , orientation ,
wl_fixed_from_double ( value ) ) ;
}
}
void wlr_seat_pointer_send_axis ( struct wlr_seat * wlr_seat , uint32_t time ,
void wlr_seat_pointer_send_axis ( struct wlr_seat * wlr_seat , uint32_t time ,
@ -336,7 +327,10 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
send_source = true ;
send_source = true ;
}
}
update_value120_accumulators ( client , orientation , value , value_discrete ) ;
double low_res_value ;
int32_t low_res_value_discrete ;
update_value120_accumulators ( client , orientation , value , value_discrete ,
& low_res_value , & low_res_value_discrete ) ;
struct wl_resource * resource ;
struct wl_resource * resource ;
wl_resource_for_each ( resource , & client - > pointers ) {
wl_resource_for_each ( resource , & client - > pointers ) {
@ -346,19 +340,36 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
uint32_t version = wl_resource_get_version ( resource ) ;
uint32_t version = wl_resource_get_version ( resource ) ;
if ( version < WL_POINTER_AXIS_VALUE120_SINCE_VERSION & &
value_discrete ! = 0 & & low_res_value_discrete = = 0 ) {
// The client doesn't support high resolution discrete scrolling
// and we haven't accumulated enough wheel clicks for a single
// low resolution event. Don't send anything.
continue ;
}
if ( send_source & & version > = WL_POINTER_AXIS_SOURCE_SINCE_VERSION ) {
if ( send_source & & version > = WL_POINTER_AXIS_SOURCE_SINCE_VERSION ) {
wl_pointer_send_axis_source ( resource , source ) ;
wl_pointer_send_axis_source ( resource , source ) ;
}
}
if ( value ) {
if ( value ) {
if ( value_discrete ) {
if ( value_discrete ) {
if ( version > = WL_POINTER_AXIS_VALUE120_SINCE_VERSION ) {
if ( version > = WL_POINTER_AXIS_VALUE120_SINCE_VERSION ) {
send_axis_value120 ( resource , time , orientation , value ,
// High resolution discrete scrolling
wl_pointer_send_axis_value120 ( resource , orientation ,
value_discrete ) ;
value_discrete ) ;
} else if ( version > = WL_POINTER_AXIS_DISCRETE_SINCE_VERSION ) {
wl_pointer_send_axis ( resource , time , orientation ,
send_axis_discrete ( client , resource , time , orientation ,
wl_fixed_from_double ( value ) ) ;
value , value_discrete ) ;
} else {
// Low resolution discrete scrolling
if ( version > = WL_POINTER_AXIS_DISCRETE_SINCE_VERSION ) {
wl_pointer_send_axis_discrete ( resource , orientation ,
low_res_value_discrete ) ;
}
wl_pointer_send_axis ( resource , time , orientation ,
wl_fixed_from_double ( low_res_value ) ) ;
}
}
} else {
} else {
// Continuous scrolling
wl_pointer_send_axis ( resource , time , orientation ,
wl_pointer_send_axis ( resource , time , orientation ,
wl_fixed_from_double ( value ) ) ;
wl_fixed_from_double ( value ) ) ;
}
}