void CLibInputPointer::ProcessAxis(libinput_event_pointer *e) { unsigned char scroll = 0; if (!libinput_event_pointer_has_axis(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) return; const double v = libinput_event_pointer_get_axis_value(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); if (v < 0) scroll = XBMC_BUTTON_WHEELUP; else scroll = XBMC_BUTTON_WHEELDOWN; XBMC_Event event; memset(&event, 0, sizeof(event)); event.type = XBMC_MOUSEBUTTONDOWN; event.button.button = scroll; event.button.x = static_cast<uint16_t>(m_pos.X); event.button.y = static_cast<uint16_t>(m_pos.Y); CLog::Log(LOGDEBUG, "CLibInputPointer::%s - scroll: %s, event.button.x: %i, event.button.y: %i", __FUNCTION__, scroll == XBMC_BUTTON_WHEELUP ? "up" : "down", event.button.x, event.button.y); std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort(); if (appPort) appPort->OnEvent(event); event.type = XBMC_MOUSEBUTTONUP; if (appPort) appPort->OnEvent(event); }
void QLibInputPointer::processAxis(libinput_event_pointer *e) { #if QT_LIBINPUT_VERSION_MAJOR == 0 && QT_LIBINPUT_VERSION_MINOR <= 7 const double v = libinput_event_pointer_get_axis_value(e) * 120; const Qt::Orientation ori = libinput_event_pointer_get_axis(e) == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL ? Qt::Vertical : Qt::Horizontal; QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), ori, QGuiApplication::keyboardModifiers()); #else if (libinput_event_pointer_has_axis(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { const double v = libinput_event_pointer_get_axis_value(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) * 120; QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), Qt::Vertical, QGuiApplication::keyboardModifiers()); } if (libinput_event_pointer_has_axis(e, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { const double v = libinput_event_pointer_get_axis_value(e, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) * 120; QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), Qt::Horizontal, QGuiApplication::keyboardModifiers()); } #endif }
static void handle_pointer_axis(struct libinput_device *libinput_device, struct libinput_event_pointer *pointer_event) { struct evdev_device *device = libinput_device_get_user_data(libinput_device); notify_axis(device->seat, libinput_event_pointer_get_time(pointer_event), libinput_event_pointer_get_axis(pointer_event), libinput_event_pointer_get_axis_value(pointer_event)); }
END_TEST static void test_wheel_event(struct litest_device *dev, int which, int amount) { struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_event_pointer *ptrev; /* the current evdev implementation scales the scroll wheel events up by a factor 10 */ const int scroll_step = 10; int expected = amount * scroll_step; /* mouse scroll wheels are 'upside down' */ if (which == REL_WHEEL) amount *= -1; litest_event(dev, EV_REL, which, amount); litest_event(dev, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event != NULL); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_AXIS); ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), which == REL_WHEEL ? LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL : LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL); ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), li_fixed_from_int(expected)); libinput_event_destroy(event); }
static double normalize_scroll(struct libinput_event_pointer *pointer_event, enum libinput_pointer_axis axis) { static int warned; enum libinput_pointer_axis_source source; double value; source = libinput_event_pointer_get_axis_source(pointer_event); /* libinput < 0.8 sent wheel click events with value 10. Since 0.8 the value is the angle of the click in degrees. To keep backwards-compat with existing clients, we just send multiples of the click count. */ switch (source) { case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: value = 10 * libinput_event_pointer_get_axis_value_discrete( pointer_event, axis); break; case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: value = libinput_event_pointer_get_axis_value(pointer_event, axis); break; default: value = 0; if (warned < 5) { weston_log("Unknown scroll source %d. Event discarded\n", source); warned++; } break; } return value; }
static int input_event(int fd, uint32_t mask, void *data) { (void)fd, (void)mask; struct input *input = data; if (libinput_dispatch(input->handle) != 0) wlc_log(WLC_LOG_WARN, "Failed to dispatch libinput"); struct libinput_event *event; while ((event = libinput_get_event(input->handle))) { struct libinput *handle = libinput_event_get_context(event); struct libinput_device *device = libinput_event_get_device(event); (void)handle; switch (libinput_event_get_type(event)) { case LIBINPUT_EVENT_DEVICE_ADDED: WLC_INTERFACE_EMIT(input.created, device); break; case LIBINPUT_EVENT_DEVICE_REMOVED: WLC_INTERFACE_EMIT(input.destroyed, device); break; case LIBINPUT_EVENT_POINTER_MOTION: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_MOTION; ev.time = libinput_event_pointer_get_time(pev); ev.motion.dx = libinput_event_pointer_get_dx(pev); ev.motion.dy = libinput_event_pointer_get_dy(pev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_MOTION_ABSOLUTE; ev.time = libinput_event_pointer_get_time(pev); ev.motion_abs.x = pointer_abs_x; ev.motion_abs.y = pointer_abs_y; ev.motion_abs.internal = pev; wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_POINTER_BUTTON: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_BUTTON; ev.time = libinput_event_pointer_get_time(pev); ev.button.code = libinput_event_pointer_get_button(pev); ev.button.state = (enum wl_pointer_button_state)libinput_event_pointer_get_button_state(pev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_POINTER_AXIS: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_SCROLL; ev.time = libinput_event_pointer_get_time(pev); #if LIBINPUT_VERSION_MAJOR == 0 && LIBINPUT_VERSION_MINOR < 8 /* < libinput 0.8.x (at least to 0.6.x) */ const enum wl_pointer_axis axis = libinput_event_pointer_get_axis(pev); ev.scroll.amount[(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)] = libinput_event_pointer_get_axis_value(pev); ev.scroll.axis_bits |= (axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL ? WLC_SCROLL_AXIS_HORIZONTAL : WLC_SCROLL_AXIS_VERTICAL); #else /* > libinput 0.8.0 */ if (libinput_event_pointer_has_axis(pev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { ev.scroll.amount[0] = libinput_event_pointer_get_axis_value(pev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); ev.scroll.axis_bits |= WLC_SCROLL_AXIS_VERTICAL; } if (libinput_event_pointer_has_axis(pev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { ev.scroll.amount[1] = libinput_event_pointer_get_axis_value(pev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); ev.scroll.axis_bits |= WLC_SCROLL_AXIS_HORIZONTAL; } #endif // We should get other axis information from libinput as well, like source (finger, wheel) (v0.8) wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_KEYBOARD_KEY: { struct libinput_event_keyboard *kev = libinput_event_get_keyboard_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_KEY; ev.time = libinput_event_keyboard_get_time(kev); ev.key.code = libinput_event_keyboard_get_key(kev); ev.key.state = (enum wl_keyboard_key_state)libinput_event_keyboard_get_key_state(kev); ev.device = device; wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_TOUCH_UP: { struct libinput_event_touch *tev = libinput_event_get_touch_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_TOUCH; ev.time = libinput_event_touch_get_time(tev); ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event)); ev.touch.slot = libinput_event_touch_get_seat_slot(tev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_TOUCH_DOWN: case LIBINPUT_EVENT_TOUCH_MOTION: { struct libinput_event_touch *tev = libinput_event_get_touch_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_TOUCH; ev.time = libinput_event_touch_get_time(tev); ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event)); ev.touch.x = touch_abs_x; ev.touch.y = touch_abs_y; ev.touch.internal = tev; ev.touch.slot = libinput_event_touch_get_seat_slot(tev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_TOUCH_FRAME: case LIBINPUT_EVENT_TOUCH_CANCEL: { struct libinput_event_touch *tev = libinput_event_get_touch_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_TOUCH; ev.time = libinput_event_touch_get_time(tev); ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event)); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; default: break; } libinput_event_destroy(event); } return 0; }
inline void LibInputHandler::HandleEvent(struct libinput_event *li_event) { int type = libinput_event_get_type(li_event); switch (type) { case LIBINPUT_EVENT_KEYBOARD_KEY: { /* Discard all data on stdin to avoid that keyboard input data is read * on the executing shell. */ tcflush(STDIN_FILENO, TCIFLUSH); libinput_event_keyboard *kb_li_event = libinput_event_get_keyboard_event(li_event); uint32_t key_code = libinput_event_keyboard_get_key(kb_li_event); libinput_key_state key_state = libinput_event_keyboard_get_key_state(kb_li_event); queue.Push(Event(key_state == LIBINPUT_KEY_STATE_PRESSED ? Event::KEY_DOWN : Event::KEY_UP, key_code)); } break; case LIBINPUT_EVENT_POINTER_MOTION: { libinput_event_pointer *ptr_li_event = libinput_event_get_pointer_event(li_event); if (-1.0 == x) x = 0.0; if (-1.0 == y) y = 0.0; x += libinput_event_pointer_get_dx(ptr_li_event); x = Clamp<double>(x, 0, width); y += libinput_event_pointer_get_dy(ptr_li_event); y = Clamp<double>(y, 0, height); queue.Push(Event(Event::MOUSE_MOTION, (unsigned) x, (unsigned) y)); } break; case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: { libinput_event_pointer *ptr_li_event = libinput_event_get_pointer_event(li_event); x = libinput_event_pointer_get_absolute_x_transformed(ptr_li_event, width); y = libinput_event_pointer_get_absolute_y_transformed(ptr_li_event, height); queue.Push(Event(Event::MOUSE_MOTION, (unsigned) x, (unsigned) y)); } break; case LIBINPUT_EVENT_POINTER_BUTTON: { libinput_event_pointer *ptr_li_event = libinput_event_get_pointer_event(li_event); libinput_button_state btn_state = libinput_event_pointer_get_button_state(ptr_li_event); queue.Push(Event(btn_state == LIBINPUT_BUTTON_STATE_PRESSED ? Event::MOUSE_DOWN : Event::MOUSE_UP, (unsigned) x, (unsigned) y)); } break; case LIBINPUT_EVENT_POINTER_AXIS: { libinput_event_pointer *ptr_li_event = libinput_event_get_pointer_event(li_event); double axis_value = libinput_event_pointer_get_axis_value(ptr_li_event); Event event(Event::MOUSE_WHEEL, (unsigned) x, (unsigned) y); event.param = unsigned((int) axis_value); queue.Push(event); } break; case LIBINPUT_EVENT_TOUCH_DOWN: { libinput_event_touch *touch_li_event = libinput_event_get_touch_event(li_event); x = libinput_event_touch_get_x_transformed(touch_li_event, width); y = libinput_event_touch_get_y_transformed(touch_li_event, height); queue.Push(Event(Event::MOUSE_DOWN, (unsigned) x, (unsigned) y)); } break; case LIBINPUT_EVENT_TOUCH_UP: { queue.Push(Event(Event::MOUSE_UP, (unsigned) x, (unsigned) y)); } break; case LIBINPUT_EVENT_TOUCH_MOTION: { libinput_event_touch *touch_li_event = libinput_event_get_touch_event(li_event); x = libinput_event_touch_get_x_transformed(touch_li_event, width); y = libinput_event_touch_get_y_transformed(touch_li_event, height); queue.Push(Event(Event::MOUSE_MOTION, (unsigned) x, (unsigned) y)); } break; } }
void LibinputServer::processEvents() { libinput_dispatch(m_libinput); while (auto* event = libinput_get_event(m_libinput)) { switch (libinput_event_get_type(event)) { case LIBINPUT_EVENT_TOUCH_DOWN: if (m_handleTouchEvents) handleTouchEvent(event, Input::TouchEvent::Type::Down); break; case LIBINPUT_EVENT_TOUCH_UP: if (m_handleTouchEvents) handleTouchEvent(event, Input::TouchEvent::Type::Up); break; case LIBINPUT_EVENT_TOUCH_MOTION: if (m_handleTouchEvents) handleTouchEvent(event, Input::TouchEvent::Type::Motion); break; case LIBINPUT_EVENT_KEYBOARD_KEY: { auto* keyEvent = libinput_event_get_keyboard_event(event); Input::KeyboardEvent::Raw rawEvent{ libinput_event_keyboard_get_time(keyEvent), libinput_event_keyboard_get_key(keyEvent), libinput_event_keyboard_get_key_state(keyEvent) }; Input::KeyboardEventHandler::Result result = m_keyboardEventHandler->handleKeyboardEvent(rawEvent); m_client->handleKeyboardEvent({ rawEvent.time, std::get<0>(result), std::get<1>(result), !!rawEvent.state, std::get<2>(result) }); if (!!rawEvent.state) m_keyboardEventRepeating->schedule(rawEvent); else m_keyboardEventRepeating->cancel(); break; } case LIBINPUT_EVENT_POINTER_MOTION: { if (!m_handlePointerEvents) break; auto* pointerEvent = libinput_event_get_pointer_event(event); double dx = libinput_event_pointer_get_dx(pointerEvent); double dy = libinput_event_pointer_get_dy(pointerEvent); m_pointerCoords.first = std::min<int32_t>(std::max<uint32_t>(0, m_pointerCoords.first + dx), m_pointerBounds.first - 1); m_pointerCoords.second = std::min<int32_t>(std::max<uint32_t>(0, m_pointerCoords.second + dy), m_pointerBounds.second - 1); m_client->handlePointerEvent({ Input::PointerEvent::Motion, libinput_event_pointer_get_time(pointerEvent), m_pointerCoords.first, m_pointerCoords.second, 0, 0 }); break; } case LIBINPUT_EVENT_POINTER_BUTTON: { if (!m_handlePointerEvents) break; auto* pointerEvent = libinput_event_get_pointer_event(event); m_client->handlePointerEvent({ Input::PointerEvent::Button, libinput_event_pointer_get_time(pointerEvent), m_pointerCoords.first, m_pointerCoords.second, libinput_event_pointer_get_button(pointerEvent), libinput_event_pointer_get_button_state(pointerEvent) }); break; } case LIBINPUT_EVENT_POINTER_AXIS: { if (!m_handlePointerEvents) break; auto* pointerEvent = libinput_event_get_pointer_event(event); // Support only wheel events for now. if (libinput_event_pointer_get_axis_source(pointerEvent) != LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) break; if (libinput_event_pointer_has_axis(pointerEvent, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { auto axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; int32_t axisValue = libinput_event_pointer_get_axis_value(pointerEvent, axis); m_client->handleAxisEvent({ Input::AxisEvent::Motion, libinput_event_pointer_get_time(pointerEvent), m_pointerCoords.first, m_pointerCoords.second, axis, -axisValue }); } if (libinput_event_pointer_has_axis(pointerEvent, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { auto axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; int32_t axisValue = libinput_event_pointer_get_axis_value(pointerEvent, axis); m_client->handleAxisEvent({ Input::AxisEvent::Motion, libinput_event_pointer_get_time(pointerEvent), m_pointerCoords.first, m_pointerCoords.second, axis, axisValue }); } break; } default: break; } libinput_event_destroy(event); } }