evdev_post_scroll(struct evdev_device *device,
		  uint64_t time,
		  enum libinput_pointer_axis_source source,
		  const struct normalized_coords *delta)
{
	const struct normalized_coords *trigger;
	struct normalized_coords event;

	if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
		device->scroll.buildup.y += delta->y;
	if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
		device->scroll.buildup.x += delta->x;

	trigger = &device->scroll.buildup;

	/* If we're not scrolling yet, use a distance trigger: moving
	   past a certain distance starts scrolling */
	if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) &&
	    !evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
		if (fabs(trigger->y) >= device->scroll.threshold)
			evdev_start_scrolling(device,
					      LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
		if (fabs(trigger->x) >= device->scroll.threshold)
			evdev_start_scrolling(device,
					      LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
	/* We're already scrolling in one direction. Require some
	   trigger speed to start scrolling in the other direction */
	} else if (!evdev_is_scrolling(device,
			       LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
		if (fabs(delta->y) >= device->scroll.direction_lock_threshold)
			evdev_start_scrolling(device,
				      LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
	} else if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
		if (fabs(delta->x) >= device->scroll.direction_lock_threshold)
			evdev_start_scrolling(device,
				      LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
	}

	event = *delta;

	/* We use the trigger to enable, but the delta from this event for
	 * the actual scroll movement. Otherwise we get a jump once
	 * scrolling engages */
	if (!evdev_is_scrolling(device,
			       LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
		event.y = 0.0;

	if (!evdev_is_scrolling(device,
			       LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
		event.x = 0.0;

	if (!normalized_is_zero(event)) {
		uint32_t axes = device->scroll.direction;

		if (event.y == 0.0)
			axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
		if (event.x == 0.0)
			axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);

		switch (source) {
		case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
			evdev_notify_axis_finger(device, time, axes, &event);
			break;
		case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
			evdev_notify_axis_continous(device, time, axes, &event);
			break;
		default:
			evdev_log_bug_libinput(device,
					       "Posting invalid scroll source %d\n",
					       source);
			break;
		}
	}
}
evdev_post_scroll(struct evdev_device *device,
		  uint64_t time,
		  enum libinput_pointer_axis_source source,
		  const struct normalized_coords *delta)
{
	const struct normalized_coords *trigger;
	struct normalized_coords event;

	if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
		device->scroll.buildup.y += delta->y;
	if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
		device->scroll.buildup.x += delta->x;

	trigger = &device->scroll.buildup;

	 
	if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) &&
	    !evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
		if (fabs(trigger->y) >= device->scroll.threshold)
			evdev_start_scrolling(device,
					      LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
		if (fabs(trigger->x) >= device->scroll.threshold)
			evdev_start_scrolling(device,
					      LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
	 
	} else if (!evdev_is_scrolling(device,
			       LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
		if (fabs(delta->y) >= device->scroll.direction_lock_threshold)
			evdev_start_scrolling(device,
				      LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
	} else if (!evdev_is_scrolling(device,
				LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
		if (fabs(delta->x) >= device->scroll.direction_lock_threshold)
			evdev_start_scrolling(device,
				      LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
	}

	event = *delta;

	 
	if (!evdev_is_scrolling(device,
			       LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
		event.y = 0.0;

	if (!evdev_is_scrolling(device,
			       LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
		event.x = 0.0;

	if (!normalized_is_zero(event)) {
		uint32_t axes = device->scroll.direction;

		if (event.y == 0.0)
			axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
		if (event.x == 0.0)
			axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);

		switch (source) {
		case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
			evdev_notify_axis_finger(device, time, axes, &event);
			break;
		case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
			evdev_notify_axis_continous(device, time, axes, &event);
			break;
		default:
			evdev_log_bug_libinput(device,
					       "Posting invalid scroll source %d\n",
					       source);
			break;
		}
	}
}