static inline void evdev_process_relative(struct evdev_device *device, struct input_event *e, uint32_t time) { struct libinput_device *base = &device->base; switch (e->code) { case REL_X: if (device->pending_event != EVDEV_RELATIVE_MOTION) evdev_flush_pending_event(device, time); device->rel.dx += li_fixed_from_int(e->value); device->pending_event = EVDEV_RELATIVE_MOTION; break; case REL_Y: if (device->pending_event != EVDEV_RELATIVE_MOTION) evdev_flush_pending_event(device, time); device->rel.dy += li_fixed_from_int(e->value); device->pending_event = EVDEV_RELATIVE_MOTION; break; case REL_WHEEL: evdev_flush_pending_event(device, time); switch (e->value) { case -1: /* Scroll down */ case 1: /* Scroll up */ pointer_notify_axis( base, time, LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, -1 * e->value * DEFAULT_AXIS_STEP_DISTANCE); break; default: break; } break; case REL_HWHEEL: evdev_flush_pending_event(device, time); switch (e->value) { case -1: /* Scroll left */ case 1: /* Scroll right */ pointer_notify_axis( base, time, LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, e->value * DEFAULT_AXIS_STEP_DISTANCE); break; default: break; } } }
static void touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time) { int motion_index; int center_x, center_y; double dx = 0.0, dy = 0.0; struct libinput_device *base = &touchpad->device->base; if (touchpad->reset || touchpad->last_finger_state != touchpad->finger_state) { touchpad->reset = 0; touchpad->motion_count = 0; touchpad->event_mask = TOUCHPAD_EVENT_NONE; touchpad->event_mask_filter = TOUCHPAD_EVENT_ABSOLUTE_X | TOUCHPAD_EVENT_ABSOLUTE_Y; touchpad->last_finger_state = touchpad->finger_state; process_fsm_events(touchpad, time); return; } touchpad->last_finger_state = touchpad->finger_state; if (!(touchpad->event_mask & TOUCHPAD_EVENT_REPORT)) return; else touchpad->event_mask &= ~TOUCHPAD_EVENT_REPORT; if ((touchpad->event_mask & touchpad->event_mask_filter) != touchpad->event_mask_filter) return; touchpad->event_mask_filter = TOUCHPAD_EVENT_ABSOLUTE_ANY; touchpad->event_mask = 0; /* Avoid noise by moving center only when delta reaches a threshold * distance from the old center. */ if (touchpad->motion_count > 0) { center_x = hysteresis(touchpad->hw_abs.x, touchpad->hysteresis.center_x, touchpad->hysteresis.margin_x); center_y = hysteresis(touchpad->hw_abs.y, touchpad->hysteresis.center_y, touchpad->hysteresis.margin_y); } else { center_x = touchpad->hw_abs.x; center_y = touchpad->hw_abs.y; } touchpad->hysteresis.center_x = center_x; touchpad->hysteresis.center_y = center_y; touchpad->hw_abs.x = center_x; touchpad->hw_abs.y = center_y; /* Update motion history tracker */ motion_index = (touchpad->motion_index + 1) % TOUCHPAD_HISTORY_LENGTH; touchpad->motion_index = motion_index; touchpad->motion_history[motion_index].x = touchpad->hw_abs.x; touchpad->motion_history[motion_index].y = touchpad->hw_abs.y; if (touchpad->motion_count < 4) touchpad->motion_count++; if (touchpad->motion_count >= 4) { touchpad_get_delta(touchpad, &dx, &dy); filter_motion(touchpad, &dx, &dy, time); if (touchpad->finger_state == TOUCHPAD_FINGERS_ONE) { pointer_notify_motion( base, time, li_fixed_from_double(dx), li_fixed_from_double(dy)); } else if (touchpad->finger_state == TOUCHPAD_FINGERS_TWO) { if (dx != 0.0) pointer_notify_axis( base, time, LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, li_fixed_from_double(dx)); if (dy != 0.0) pointer_notify_axis( base, time, LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, li_fixed_from_double(dy)); } } if (!(touchpad->state & TOUCHPAD_STATE_MOVE) && ((int)dx || (int)dy)) { touchpad->state |= TOUCHPAD_STATE_MOVE; push_fsm_event(touchpad, FSM_EVENT_MOTION); } process_fsm_events(touchpad, time); }