diff --git a/autotests/libinput/mock_libinput.cpp b/autotests/libinput/mock_libinput.cpp index 4f298ff52..a9532ed22 100644 --- a/autotests/libinput/mock_libinput.cpp +++ b/autotests/libinput/mock_libinput.cpp @@ -1,624 +1,651 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include #include "mock_libinput.h" #include #include int libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code) { return device->keys.contains(code); } int libinput_device_has_capability(struct libinput_device *device, enum libinput_device_capability capability) { switch (capability) { case LIBINPUT_DEVICE_CAP_KEYBOARD: return device->keyboard; case LIBINPUT_DEVICE_CAP_POINTER: return device->pointer; case LIBINPUT_DEVICE_CAP_TOUCH: return device->touch; case LIBINPUT_DEVICE_CAP_GESTURE: return device->gestureSupported; case LIBINPUT_DEVICE_CAP_TABLET_TOOL: return device->tabletTool; default: return 0; } } const char *libinput_device_get_name(struct libinput_device *device) { return device->name.constData(); } const char *libinput_device_get_sysname(struct libinput_device *device) { return device->sysName.constData(); } const char *libinput_device_get_output_name(struct libinput_device *device) { return device->outputName.constData(); } unsigned int libinput_device_get_id_product(struct libinput_device *device) { return device->product; } unsigned int libinput_device_get_id_vendor(struct libinput_device *device) { return device->vendor; } int libinput_device_config_tap_get_finger_count(struct libinput_device *device) { return device->tapFingerCount; } enum libinput_config_tap_state libinput_device_config_tap_get_enabled(struct libinput_device *device) { if (device->tapToClick) { return LIBINPUT_CONFIG_TAP_ENABLED; } else { return LIBINPUT_CONFIG_TAP_DISABLED; } } enum libinput_config_status libinput_device_config_tap_set_enabled(struct libinput_device *device, enum libinput_config_tap_state enable) { if (device->setTapToClickReturnValue == 0) { device->tapToClick = (enable == LIBINPUT_CONFIG_TAP_ENABLED); return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } enum libinput_config_tap_state libinput_device_config_tap_get_default_enabled(struct libinput_device *device) { if (device->tapEnabledByDefault) { return LIBINPUT_CONFIG_TAP_ENABLED; } else { return LIBINPUT_CONFIG_TAP_DISABLED; } } enum libinput_config_drag_state libinput_device_config_tap_get_default_drag_enabled(struct libinput_device *device) { if (device->tapAndDragEnabledByDefault) { return LIBINPUT_CONFIG_DRAG_ENABLED; } else { return LIBINPUT_CONFIG_DRAG_DISABLED; } } enum libinput_config_drag_state libinput_device_config_tap_get_drag_enabled(struct libinput_device *device) { if (device->tapAndDrag) { return LIBINPUT_CONFIG_DRAG_ENABLED; } else { return LIBINPUT_CONFIG_DRAG_DISABLED; } } enum libinput_config_status libinput_device_config_tap_set_drag_enabled(struct libinput_device *device, enum libinput_config_drag_state enable) { if (device->setTapAndDragReturnValue == 0) { device->tapAndDrag = (enable == LIBINPUT_CONFIG_DRAG_ENABLED); return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } enum libinput_config_drag_lock_state libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device) { if (device->tapDragLockEnabledByDefault) { return LIBINPUT_CONFIG_DRAG_LOCK_ENABLED; } else { return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; } } enum libinput_config_drag_lock_state libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device) { if (device->tapDragLock) { return LIBINPUT_CONFIG_DRAG_LOCK_ENABLED; } else { return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; } } enum libinput_config_status libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device *device, enum libinput_config_drag_lock_state enable) { if (device->setTapDragLockReturnValue == 0) { device->tapDragLock = (enable == LIBINPUT_CONFIG_DRAG_LOCK_ENABLED); return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } int libinput_device_config_dwt_is_available(struct libinput_device *device) { return device->supportsDisableWhileTyping; } int libinput_device_config_accel_is_available(struct libinput_device *device) { return device->supportsPointerAcceleration; } int libinput_device_config_calibration_has_matrix(struct libinput_device *device) { return device->supportsCalibrationMatrix; } int libinput_device_config_left_handed_is_available(struct libinput_device *device) { return device->supportsLeftHanded; } uint32_t libinput_device_config_send_events_get_modes(struct libinput_device *device) { uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; if (device->supportsDisableEvents) { modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED; } if (device->supportsDisableEventsOnExternalMouse) { modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; } return modes; } int libinput_device_config_left_handed_get(struct libinput_device *device) { return device->leftHanded; } double libinput_device_config_accel_get_speed(struct libinput_device *device) { return device->pointerAcceleration; } uint32_t libinput_device_config_send_events_get_mode(struct libinput_device *device) { if (device->enabled) { return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; } else { // TODO: disabled on eternal mouse return LIBINPUT_CONFIG_SEND_EVENTS_DISABLED; } } struct libinput_device *libinput_device_ref(struct libinput_device *device) { return device; } struct libinput_device *libinput_device_unref(struct libinput_device *device) { return device; } int libinput_device_get_size(struct libinput_device *device, double *width, double *height) { if (device->deviceSizeReturnValue) { return device->deviceSizeReturnValue; } if (width) { *width = device->deviceSize.width(); } if (height) { *height = device->deviceSize.height(); } return device->deviceSizeReturnValue; } int libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code) { switch (code) { case BTN_LEFT: return device->supportedButtons.testFlag(Qt::LeftButton); case BTN_MIDDLE: return device->supportedButtons.testFlag(Qt::MiddleButton); case BTN_RIGHT: return device->supportedButtons.testFlag(Qt::RightButton); case BTN_SIDE: return device->supportedButtons.testFlag(Qt::ExtraButton1); case BTN_EXTRA: return device->supportedButtons.testFlag(Qt::ExtraButton2); case BTN_BACK: return device->supportedButtons.testFlag(Qt::BackButton); case BTN_FORWARD: return device->supportedButtons.testFlag(Qt::ForwardButton); case BTN_TASK: return device->supportedButtons.testFlag(Qt::TaskButton); default: return 0; } } enum libinput_config_status libinput_device_config_left_handed_set(struct libinput_device *device, int left_handed) { if (device->setLeftHandedReturnValue == 0) { device->leftHanded = left_handed; return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } enum libinput_config_status libinput_device_config_accel_set_speed(struct libinput_device *device, double speed) { if (device->setPointerAccelerationReturnValue == 0) { device->pointerAcceleration = speed; return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } enum libinput_config_status libinput_device_config_send_events_set_mode(struct libinput_device *device, uint32_t mode) { if (device->setEnableModeReturnValue == 0) { device->enabled = (mode == LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } enum libinput_event_type libinput_event_get_type(struct libinput_event *event) { return event->type; } struct libinput_device *libinput_event_get_device(struct libinput_event *event) { return event->device; } void libinput_event_destroy(struct libinput_event *event) { delete event; } struct libinput_event_keyboard *libinput_event_get_keyboard_event(struct libinput_event *event) { if (event->type == LIBINPUT_EVENT_KEYBOARD_KEY) { return reinterpret_cast(event); } return nullptr; } struct libinput_event_pointer *libinput_event_get_pointer_event(struct libinput_event *event) { if (event->type == LIBINPUT_EVENT_POINTER_MOTION || event->type == LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE || event->type == LIBINPUT_EVENT_POINTER_BUTTON || event->type == LIBINPUT_EVENT_POINTER_AXIS) { return reinterpret_cast(event); } return nullptr; } struct libinput_event_touch *libinput_event_get_touch_event(struct libinput_event *event) { if (event->type == LIBINPUT_EVENT_TOUCH_DOWN || event->type == LIBINPUT_EVENT_TOUCH_UP || event->type == LIBINPUT_EVENT_TOUCH_MOTION || event->type == LIBINPUT_EVENT_TOUCH_CANCEL || event->type == LIBINPUT_EVENT_TOUCH_FRAME) { return reinterpret_cast(event); } return nullptr; } struct libinput_event_gesture *libinput_event_get_gesture_event(struct libinput_event *event) { if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN || event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE || event->type == LIBINPUT_EVENT_GESTURE_PINCH_END || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_END) { return reinterpret_cast(event); } return nullptr; } int libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event) { if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_END || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_END) { return event->cancelled; } return 0; } uint32_t libinput_event_gesture_get_time(struct libinput_event_gesture *event) { return event->time; } int libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event) { return event->fingerCount; } double libinput_event_gesture_get_dx(struct libinput_event_gesture *event) { if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE) { return event->delta.width(); } return 0.0; } double libinput_event_gesture_get_dy(struct libinput_event_gesture *event) { if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE) { return event->delta.height(); } return 0.0; } double libinput_event_gesture_get_scale(struct libinput_event_gesture *event) { switch (event->type) { case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: return 1.0; case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: case LIBINPUT_EVENT_GESTURE_PINCH_END: return event->scale; default: return 0.0; } } double libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event) { if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE) { return event->angleDelta; } return 0.0; } uint32_t libinput_event_keyboard_get_key(struct libinput_event_keyboard *event) { return event->key; } enum libinput_key_state libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event) { return event->state; } uint32_t libinput_event_keyboard_get_time(struct libinput_event_keyboard *event) { return event->time; } double libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) { return event->absolutePos.x(); } double libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) { return event->absolutePos.y(); } double libinput_event_pointer_get_absolute_x_transformed(struct libinput_event_pointer *event, uint32_t width) { double deviceWidth = 0.0; double deviceHeight = 0.0; libinput_device_get_size(event->device, &deviceWidth, &deviceHeight); return event->absolutePos.x() / deviceWidth * width; } double libinput_event_pointer_get_absolute_y_transformed(struct libinput_event_pointer *event, uint32_t height) { double deviceWidth = 0.0; double deviceHeight = 0.0; libinput_device_get_size(event->device, &deviceWidth, &deviceHeight); return event->absolutePos.y() / deviceHeight * height; } double libinput_event_pointer_get_dx(struct libinput_event_pointer *event) { return event->delta.width(); } double libinput_event_pointer_get_dy(struct libinput_event_pointer *event) { return event->delta.height(); } uint32_t libinput_event_pointer_get_time(struct libinput_event_pointer *event) { return event->time; } uint32_t libinput_event_pointer_get_button(struct libinput_event_pointer *event) { return event->button; } enum libinput_button_state libinput_event_pointer_get_button_state(struct libinput_event_pointer *event) { return event->buttonState; } int libinput_event_pointer_has_axis(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) { if (axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) { return event->verticalAxis; } else { return event->horizontalAxis; } } double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) { if (axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) { return event->verticalAxisValue; } else { return event->horizontalAxisValue; } } uint32_t libinput_event_touch_get_time(struct libinput_event_touch *event) { return event->time; } double libinput_event_touch_get_x(struct libinput_event_touch *event) { return event->absolutePos.x(); } double libinput_event_touch_get_y(struct libinput_event_touch *event) { return event->absolutePos.y(); } double libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, uint32_t width) { double deviceWidth = 0.0; double deviceHeight = 0.0; libinput_device_get_size(event->device, &deviceWidth, &deviceHeight); return event->absolutePos.x() / deviceWidth * width; } double libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, uint32_t height) { double deviceWidth = 0.0; double deviceHeight = 0.0; libinput_device_get_size(event->device, &deviceWidth, &deviceHeight); return event->absolutePos.y() / deviceHeight * height; } int32_t libinput_event_touch_get_slot(struct libinput_event_touch *event) { return event->slot; } struct libinput *libinput_udev_create_context(const struct libinput_interface *interface, void *user_data, struct udev *udev) { if (!udev) { return nullptr; } Q_UNUSED(interface) Q_UNUSED(user_data) return new libinput; } void libinput_log_set_priority(struct libinput *libinput, enum libinput_log_priority priority) { Q_UNUSED(libinput) Q_UNUSED(priority) } void libinput_log_set_handler(struct libinput *libinput, libinput_log_handler log_handler) { Q_UNUSED(libinput) Q_UNUSED(log_handler) } struct libinput *libinput_unref(struct libinput *libinput) { libinput->refCount--; if (libinput->refCount == 0) { delete libinput; return nullptr; } return libinput; } int libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) { if (libinput->assignSeatRetVal == 0) { libinput->seat = QByteArray(seat_id); } return libinput->assignSeatRetVal; } int libinput_get_fd(struct libinput *libinput) { Q_UNUSED(libinput) return -1; } int libinput_dispatch(struct libinput *libinput) { Q_UNUSED(libinput) return 0; } struct libinput_event *libinput_get_event(struct libinput *libinput) { Q_UNUSED(libinput) return nullptr; } void libinput_suspend(struct libinput *libinput) { Q_UNUSED(libinput) } int libinput_resume(struct libinput *libinput) { Q_UNUSED(libinput) return 0; } int libinput_device_config_middle_emulation_is_available(struct libinput_device *device) { return device->supportsMiddleEmulation; } enum libinput_config_status libinput_device_config_middle_emulation_set_enabled(struct libinput_device *device, enum libinput_config_middle_emulation_state enable) { if (device->setMiddleEmulationReturnValue == 0) { if (!device->supportsMiddleEmulation) { return LIBINPUT_CONFIG_STATUS_INVALID; } device->middleEmulation = (enable == LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED); return LIBINPUT_CONFIG_STATUS_SUCCESS; } return LIBINPUT_CONFIG_STATUS_INVALID; } enum libinput_config_middle_emulation_state libinput_device_config_middle_emulation_get_enabled(struct libinput_device *device) { if (device->middleEmulation) { return LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED; } else { return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; } } enum libinput_config_middle_emulation_state libinput_device_config_middle_emulation_get_default_enabled(struct libinput_device *device) { if (device->middleEmulationEnabledByDefault) { return LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED; } else { return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; } } + +int libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device) +{ + return device->supportsNaturalScroll; +} + +enum libinput_config_status libinput_device_config_scroll_set_natural_scroll_enabled(struct libinput_device *device, int enable) +{ + if (device->setNaturalScrollReturnValue == 0) { + if (!device->supportsNaturalScroll) { + return LIBINPUT_CONFIG_STATUS_INVALID; + } + device->naturalScroll = enable; + return LIBINPUT_CONFIG_STATUS_SUCCESS; + } + return LIBINPUT_CONFIG_STATUS_INVALID; +} + +int libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device *device) +{ + return device->naturalScroll; +} + +int libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device *device) +{ + return device->naturalScrollEnabledByDefault; +} diff --git a/autotests/libinput/mock_libinput.h b/autotests/libinput/mock_libinput.h index 99864a31f..0e98543e4 100644 --- a/autotests/libinput/mock_libinput.h +++ b/autotests/libinput/mock_libinput.h @@ -1,116 +1,120 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #ifndef MOCK_LIBINPUT_H #define MOCK_LIBINPUT_H #include #include #include #include #include struct libinput_device { bool keyboard = false; bool pointer = false; bool touch = false; bool tabletTool = false; bool gestureSupported = false; QByteArray name; QByteArray sysName = QByteArrayLiteral("event0"); QByteArray outputName; quint32 product = 0; quint32 vendor = 0; int tapFingerCount = 0; QSizeF deviceSize; int deviceSizeReturnValue = 0; bool tapEnabledByDefault = false; bool tapToClick = false; bool tapAndDragEnabledByDefault = false; bool tapAndDrag = false; bool tapDragLockEnabledByDefault = false; bool tapDragLock = false; bool supportsDisableWhileTyping = false; bool supportsPointerAcceleration = false; bool supportsLeftHanded = false; bool supportsCalibrationMatrix = false; bool supportsDisableEvents = false; bool supportsDisableEventsOnExternalMouse = false; bool supportsMiddleEmulation = false; + bool supportsNaturalScroll = false; bool middleEmulationEnabledByDefault = false; bool middleEmulation = false; qreal pointerAcceleration = 0.0; int setPointerAccelerationReturnValue = 0; bool leftHanded = false; int setLeftHandedReturnValue = 0; + bool naturalScrollEnabledByDefault = false; + bool naturalScroll = false; + int setNaturalScrollReturnValue = 0; Qt::MouseButtons supportedButtons; QVector keys; bool enabled = true; int setEnableModeReturnValue = 0; int setTapToClickReturnValue = 0; int setTapAndDragReturnValue = 0; int setTapDragLockReturnValue = 0; int setMiddleEmulationReturnValue = 0; }; struct libinput_event { libinput_device *device = nullptr; libinput_event_type type = LIBINPUT_EVENT_NONE; quint32 time = 0; }; struct libinput_event_keyboard : libinput_event { libinput_event_keyboard() { type = LIBINPUT_EVENT_KEYBOARD_KEY; } libinput_key_state state = LIBINPUT_KEY_STATE_RELEASED; quint32 key = 0; }; struct libinput_event_pointer : libinput_event { libinput_button_state buttonState = LIBINPUT_BUTTON_STATE_RELEASED; quint32 button = 0; bool verticalAxis = false; bool horizontalAxis = false; qreal horizontalAxisValue = 0.0; qreal verticalAxisValue = 0.0; QSizeF delta; QPointF absolutePos; }; struct libinput_event_touch : libinput_event { qint32 slot = -1; QPointF absolutePos; }; struct libinput_event_gesture : libinput_event { int fingerCount = 0; bool cancelled = false; QSizeF delta = QSizeF(0, 0); qreal scale = 0.0; qreal angleDelta = 0.0; }; struct libinput { int refCount = 1; QByteArray seat; int assignSeatRetVal = 0; }; #endif diff --git a/libinput/device.cpp b/libinput/device.cpp index ff199fc0c..ef6e55dbb 100644 --- a/libinput/device.cpp +++ b/libinput/device.cpp @@ -1,215 +1,231 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "device.h" #include #include #include #include namespace KWin { namespace LibInput { static bool checkAlphaNumericKeyboard(libinput_device *device) { for (uint i = KEY_1; i <= KEY_0; i++) { if (libinput_device_keyboard_has_key(device, i) == 0) { return false; } } for (uint i = KEY_Q; i <= KEY_P; i++) { if (libinput_device_keyboard_has_key(device, i) == 0) { return false; } } for (uint i = KEY_A; i <= KEY_L; i++) { if (libinput_device_keyboard_has_key(device, i) == 0) { return false; } } for (uint i = KEY_Z; i <= KEY_M; i++) { if (libinput_device_keyboard_has_key(device, i) == 0) { return false; } } return true; } QVector Device::s_devices; Device *Device::getDevice(libinput_device *native) { auto it = std::find_if(s_devices.constBegin(), s_devices.constEnd(), [native] (const Device *d) { return d->device() == native; } ); if (it != s_devices.constEnd()) { return *it; } return nullptr; } Device::Device(libinput_device *device, QObject *parent) : QObject(parent) , m_device(device) , m_keyboard(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_KEYBOARD)) , m_pointer(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_POINTER)) , m_touch(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TOUCH)) , m_tabletTool(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) #if 0 // next libinput version , m_tabletPad(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TABLET_PAD)) #else , m_tabletPad(false) #endif , m_supportsGesture(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_GESTURE)) , m_name(QString::fromLocal8Bit(libinput_device_get_name(m_device))) , m_sysName(QString::fromLocal8Bit(libinput_device_get_sysname(m_device))) , m_outputName(QString::fromLocal8Bit(libinput_device_get_output_name(m_device))) , m_product(libinput_device_get_id_product(m_device)) , m_vendor(libinput_device_get_id_vendor(m_device)) , m_tapFingerCount(libinput_device_config_tap_get_finger_count(m_device)) , m_tapToClickEnabledByDefault(libinput_device_config_tap_get_default_enabled(m_device) == LIBINPUT_CONFIG_TAP_ENABLED) , m_tapToClick(libinput_device_config_tap_get_enabled(m_device)) , m_tapAndDragEnabledByDefault(libinput_device_config_tap_get_default_drag_enabled(m_device)) , m_tapAndDrag(libinput_device_config_tap_get_drag_enabled(m_device)) , m_tapDragLockEnabledByDefault(libinput_device_config_tap_get_default_drag_lock_enabled(m_device)) , m_tapDragLock(libinput_device_config_tap_get_drag_lock_enabled(m_device)) , m_supportsDisableWhileTyping(libinput_device_config_dwt_is_available(m_device)) , m_supportsPointerAcceleration(libinput_device_config_accel_is_available(m_device)) , m_supportsLeftHanded(libinput_device_config_left_handed_is_available(m_device)) , m_supportsCalibrationMatrix(libinput_device_config_calibration_has_matrix(m_device)) , m_supportsDisableEvents(libinput_device_config_send_events_get_modes(m_device) & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED) , m_supportsDisableEventsOnExternalMouse(libinput_device_config_send_events_get_modes(m_device) & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE) , m_supportsMiddleEmulation(libinput_device_config_middle_emulation_is_available(m_device)) + , m_supportsNaturalScroll(libinput_device_config_scroll_has_natural_scroll(m_device)) , m_middleEmulationEnabledByDefault(libinput_device_config_middle_emulation_get_default_enabled(m_device) == LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED) + , m_naturalScrollEnabledByDefault(libinput_device_config_scroll_get_default_natural_scroll_enabled(m_device)) , m_middleEmulation(libinput_device_config_middle_emulation_get_enabled(m_device) == LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED) , m_leftHanded(m_supportsLeftHanded ? libinput_device_config_left_handed_get(m_device) : false) + , m_naturalScroll(m_supportsNaturalScroll ? libinput_device_config_scroll_get_natural_scroll_enabled(m_device) : false) , m_pointerAcceleration(libinput_device_config_accel_get_speed(m_device)) , m_enabled(m_supportsDisableEvents ? libinput_device_config_send_events_get_mode(m_device) == LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : true) { libinput_device_ref(m_device); qreal width = 0; qreal height = 0; if (libinput_device_get_size(m_device, &width, &height) == 0) { m_size = QSizeF(width, height); } if (m_pointer) { if (libinput_device_pointer_has_button(m_device, BTN_LEFT) == 1) { m_supportedButtons |= Qt::LeftButton; } if (libinput_device_pointer_has_button(m_device, BTN_MIDDLE) == 1) { m_supportedButtons |= Qt::MiddleButton; } if (libinput_device_pointer_has_button(m_device, BTN_RIGHT) == 1) { m_supportedButtons |= Qt::RightButton; } if (libinput_device_pointer_has_button(m_device, BTN_SIDE) == 1) { m_supportedButtons |= Qt::ExtraButton1; } if (libinput_device_pointer_has_button(m_device, BTN_EXTRA) == 1) { m_supportedButtons |= Qt::ExtraButton2; } if (libinput_device_pointer_has_button(m_device, BTN_BACK) == 1) { m_supportedButtons |= Qt::BackButton; } if (libinput_device_pointer_has_button(m_device, BTN_FORWARD) == 1) { m_supportedButtons |= Qt::ForwardButton; } if (libinput_device_pointer_has_button(m_device, BTN_TASK) == 1) { m_supportedButtons |= Qt::TaskButton; } } if (m_keyboard) { m_alphaNumericKeyboard = checkAlphaNumericKeyboard(m_device); } s_devices << this; QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/InputDevice/") + m_sysName, QStringLiteral("org.kde.KWin.InputDevice"), this, QDBusConnection::ExportAllProperties ); } Device::~Device() { s_devices.removeOne(this); QDBusConnection::sessionBus().unregisterObject(QStringLiteral("/org/kde/KWin/InputDevice/") + m_sysName); libinput_device_unref(m_device); } void Device::setLeftHanded(bool set) { if (!m_supportsLeftHanded) { return; } if (libinput_device_config_left_handed_set(m_device, set) == LIBINPUT_CONFIG_STATUS_SUCCESS) { if (m_leftHanded != set) { m_leftHanded = set; emit leftHandedChanged(); } } } void Device::setPointerAcceleration(qreal acceleration) { if (!m_supportsPointerAcceleration) { return; } acceleration = qBound(-1.0, acceleration, 1.0); if (libinput_device_config_accel_set_speed(m_device, acceleration) == LIBINPUT_CONFIG_STATUS_SUCCESS) { if (m_pointerAcceleration != acceleration) { m_pointerAcceleration = acceleration; emit pointerAccelerationChanged(); } } } +void Device::setNaturalScroll(bool set) +{ + if (!m_supportsNaturalScroll) { + return; + } + if (libinput_device_config_scroll_set_natural_scroll_enabled(m_device, set) == LIBINPUT_CONFIG_STATUS_SUCCESS) { + if (m_naturalScroll != set) { + m_naturalScroll = set; + emit naturalScrollChanged(); + } + } +} + #define CONFIG(method, condition, function, enum, variable) \ void Device::method(bool set) \ { \ if (condition) { \ return; \ } \ if (libinput_device_config_##function(m_device, set ? LIBINPUT_CONFIG_##enum##_ENABLED : LIBINPUT_CONFIG_##enum##_DISABLED) == LIBINPUT_CONFIG_STATUS_SUCCESS) { \ if (m_##variable != set) { \ m_##variable = set; \ emit variable##Changed(); \ }\ } \ } CONFIG(setEnabled, !m_supportsDisableEvents, send_events_set_mode, SEND_EVENTS, enabled) CONFIG(setTapToClick, m_tapFingerCount == 0, tap_set_enabled, TAP, tapToClick) CONFIG(setTapAndDrag, false, tap_set_drag_enabled, DRAG, tapAndDrag) CONFIG(setTapDragLock, false, tap_set_drag_lock_enabled, DRAG_LOCK, tapDragLock) CONFIG(setMiddleEmulation, m_supportsMiddleEmulation == false, middle_emulation_set_enabled, MIDDLE_EMULATION, middleEmulation) #undef CONFIG } } diff --git a/libinput/device.h b/libinput/device.h index 5c37031ff..365ed74d5 100644 --- a/libinput/device.h +++ b/libinput/device.h @@ -1,263 +1,280 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #ifndef KWIN_LIBINPUT_DEVICE_H #define KWIN_LIBINPUT_DEVICE_H #include #include #include struct libinput_device; namespace KWin { namespace LibInput { class Device : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.KWin.InputDevice") Q_PROPERTY(bool keyboard READ isKeyboard CONSTANT) Q_PROPERTY(bool alphaNumericKeyboard READ isAlphaNumericKeyboard CONSTANT) Q_PROPERTY(bool pointer READ isPointer CONSTANT) Q_PROPERTY(bool touch READ isTouch CONSTANT) Q_PROPERTY(bool tabletTool READ isTabletTool CONSTANT) Q_PROPERTY(bool tabletPad READ isTabletPad CONSTANT) Q_PROPERTY(bool gestureSupport READ supportsGesture CONSTANT) Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString sysName READ sysName CONSTANT) Q_PROPERTY(QString outputName READ outputName CONSTANT) Q_PROPERTY(QSizeF size READ size CONSTANT) Q_PROPERTY(quint32 product READ product CONSTANT) Q_PROPERTY(quint32 vendor READ vendor CONSTANT) Q_PROPERTY(Qt::MouseButtons supportedButtons READ supportedButtons CONSTANT) Q_PROPERTY(int tapFingerCount READ tapFingerCount CONSTANT) Q_PROPERTY(bool tapToClickEnabledByDefault READ tapToClickEnabledByDefault CONSTANT) Q_PROPERTY(bool supportsDisableWhileTyping READ supportsDisableWhileTyping CONSTANT) Q_PROPERTY(bool supportsPointerAcceleration READ supportsPointerAcceleration CONSTANT) Q_PROPERTY(bool supportsLeftHanded READ supportsLeftHanded CONSTANT) Q_PROPERTY(bool supportsCalibrationMatrix READ supportsCalibrationMatrix CONSTANT) Q_PROPERTY(bool supportsDisableEvents READ supportsDisableEvents CONSTANT) Q_PROPERTY(bool supportsDisableEventsOnExternalMouse READ supportsDisableEventsOnExternalMouse CONSTANT) Q_PROPERTY(bool supportsMiddleEmulation READ supportsMiddleEmulation CONSTANT) + Q_PROPERTY(bool supportsNaturalScroll READ supportsNaturalScroll CONSTANT) Q_PROPERTY(bool middleEmulationEnabledByDefault READ middleEmulationEnabledByDefault CONSTANT) + Q_PROPERTY(bool naturalScrollEnabledByDefault READ naturalScrollEnabledByDefault CONSTANT) Q_PROPERTY(bool middleEmulation READ isMiddleEmulation WRITE setMiddleEmulation NOTIFY middleEmulationChanged) Q_PROPERTY(bool leftHanded READ isLeftHanded WRITE setLeftHanded NOTIFY leftHandedChanged) + Q_PROPERTY(bool naturalScroll READ isNaturalScroll WRITE setNaturalScroll NOTIFY naturalScrollChanged) Q_PROPERTY(qreal pointerAcceleration READ pointerAcceleration WRITE setPointerAcceleration NOTIFY pointerAccelerationChanged) Q_PROPERTY(bool tapToClick READ isTapToClick WRITE setTapToClick NOTIFY tapToClickChanged) Q_PROPERTY(bool tapAndDragEnabledByDefault READ tapAndDragEnabledByDefault CONSTANT) Q_PROPERTY(bool tapAndDrag READ isTapAndDrag WRITE setTapAndDrag NOTIFY tapAndDragChanged) Q_PROPERTY(bool tapDragLockEnabledByDefault READ tapDragLockEnabledByDefault CONSTANT) Q_PROPERTY(bool tapDragLock READ isTapDragLock WRITE setTapDragLock NOTIFY tapDragLockChanged) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) public: explicit Device(libinput_device *device, QObject *parent = nullptr); virtual ~Device(); bool isKeyboard() const { return m_keyboard; } bool isAlphaNumericKeyboard() const { return m_alphaNumericKeyboard; } bool isPointer() const { return m_pointer; } bool isTouch() const { return m_touch; } bool isTabletTool() const { return m_tabletTool; } bool isTabletPad() const { return m_tabletPad; } bool supportsGesture() const { return m_supportsGesture; } QString name() const { return m_name; } QString sysName() const { return m_sysName; } QString outputName() const { return m_outputName; } QSizeF size() const { return m_size; } quint32 product() const { return m_product; } quint32 vendor() const { return m_vendor; } Qt::MouseButtons supportedButtons() const { return m_supportedButtons; } int tapFingerCount() const { return m_tapFingerCount; } bool tapToClickEnabledByDefault() const { return m_tapToClickEnabledByDefault; } bool isTapToClick() const { return m_tapToClick; } /** * Set the Device to tap to click if @p set is @c true. **/ void setTapToClick(bool set); bool tapAndDragEnabledByDefault() const { return m_tapAndDragEnabledByDefault; } bool isTapAndDrag() const { return m_tapAndDrag; } void setTapAndDrag(bool set); bool tapDragLockEnabledByDefault() const { return m_tapDragLockEnabledByDefault; } bool isTapDragLock() const { return m_tapDragLock; } void setTapDragLock(bool set); bool supportsDisableWhileTyping() const { return m_supportsDisableWhileTyping; } bool supportsPointerAcceleration() const { return m_supportsPointerAcceleration; } bool supportsLeftHanded() const { return m_supportsLeftHanded; } bool supportsCalibrationMatrix() const { return m_supportsCalibrationMatrix; } bool supportsDisableEvents() const { return m_supportsDisableEvents; } bool supportsDisableEventsOnExternalMouse() const { return m_supportsDisableEventsOnExternalMouse; } bool supportsMiddleEmulation() const { return m_supportsMiddleEmulation; } + bool supportsNaturalScroll() const { + return m_supportsNaturalScroll; + } bool middleEmulationEnabledByDefault() const { return m_middleEmulationEnabledByDefault; } + bool naturalScrollEnabledByDefault() const { + return m_naturalScrollEnabledByDefault; + } bool isMiddleEmulation() const { return m_middleEmulation; } void setMiddleEmulation(bool set); + bool isNaturalScroll() const { + return m_naturalScroll; + } + void setNaturalScroll(bool set); bool isLeftHanded() const { return m_leftHanded; } /** * Sets the Device to left handed mode if @p set is @c true. * If @p set is @c false the device is set to right handed mode **/ void setLeftHanded(bool set); qreal pointerAcceleration() const { return m_pointerAcceleration; } /** * @param acceleration mapped to range [-1,1] with -1 being the slowest, 1 being the fastest supported acceleration. **/ void setPointerAcceleration(qreal acceleration); bool isEnabled() const { return m_enabled; } void setEnabled(bool enabled); libinput_device *device() const { return m_device; } /** * All created Devices **/ static QVector devices() { return s_devices; } /** * Gets the Device for @p native. @c null if there is no Device for @p native. **/ static Device *getDevice(libinput_device *native); Q_SIGNALS: void leftHandedChanged(); void pointerAccelerationChanged(); void enabledChanged(); void tapToClickChanged(); void tapAndDragChanged(); void tapDragLockChanged(); void middleEmulationChanged(); + void naturalScrollChanged(); private: libinput_device *m_device; bool m_keyboard; bool m_alphaNumericKeyboard = false; bool m_pointer; bool m_touch; bool m_tabletTool; bool m_tabletPad; bool m_supportsGesture; QString m_name; QString m_sysName; QString m_outputName; QSizeF m_size; quint32 m_product; quint32 m_vendor; Qt::MouseButtons m_supportedButtons = Qt::NoButton; int m_tapFingerCount; bool m_tapToClickEnabledByDefault; bool m_tapToClick; bool m_tapAndDragEnabledByDefault; bool m_tapAndDrag; bool m_tapDragLockEnabledByDefault; bool m_tapDragLock; bool m_supportsDisableWhileTyping; bool m_supportsPointerAcceleration; bool m_supportsLeftHanded; bool m_supportsCalibrationMatrix; bool m_supportsDisableEvents; bool m_supportsDisableEventsOnExternalMouse; bool m_supportsMiddleEmulation; + bool m_supportsNaturalScroll; bool m_middleEmulationEnabledByDefault; + bool m_naturalScrollEnabledByDefault; bool m_middleEmulation; bool m_leftHanded; + bool m_naturalScroll; qreal m_pointerAcceleration; bool m_enabled; static QVector s_devices; }; } } Q_DECLARE_METATYPE(KWin::LibInput::Device*) #endif