File indexing completed on 2024-11-10 04:56:32

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include "input.h"
0012 
0013 #include <libinput.h>
0014 
0015 namespace KWin
0016 {
0017 namespace LibInput
0018 {
0019 
0020 class Device;
0021 
0022 class Event
0023 {
0024 public:
0025     virtual ~Event();
0026 
0027     libinput_event_type type() const;
0028     Device *device() const;
0029     libinput_device *nativeDevice() const;
0030 
0031     operator libinput_event *()
0032     {
0033         return m_event;
0034     }
0035     operator libinput_event *() const
0036     {
0037         return m_event;
0038     }
0039 
0040     static std::unique_ptr<Event> create(libinput_event *event);
0041 
0042 protected:
0043     Event(libinput_event *event, libinput_event_type type);
0044 
0045 private:
0046     libinput_event *m_event;
0047     libinput_event_type m_type;
0048     mutable Device *m_device;
0049 };
0050 
0051 class KeyEvent : public Event
0052 {
0053 public:
0054     KeyEvent(libinput_event *event);
0055     ~KeyEvent() override;
0056 
0057     uint32_t key() const;
0058     InputRedirection::KeyboardKeyState state() const;
0059     std::chrono::microseconds time() const;
0060 
0061     operator libinput_event_keyboard *()
0062     {
0063         return m_keyboardEvent;
0064     }
0065     operator libinput_event_keyboard *() const
0066     {
0067         return m_keyboardEvent;
0068     }
0069 
0070 private:
0071     libinput_event_keyboard *m_keyboardEvent;
0072 };
0073 
0074 class PointerEvent : public Event
0075 {
0076 public:
0077     PointerEvent(libinput_event *event, libinput_event_type type);
0078     ~PointerEvent() override;
0079 
0080     QPointF absolutePos() const;
0081     QPointF absolutePos(const QSize &size) const;
0082     QPointF delta() const;
0083     QPointF deltaUnaccelerated() const;
0084     uint32_t button() const;
0085     InputRedirection::PointerButtonState buttonState() const;
0086     std::chrono::microseconds time() const;
0087     QList<InputRedirection::PointerAxis> axis() const;
0088     qreal scrollValue(InputRedirection::PointerAxis a) const;
0089     qint32 scrollValueV120(InputRedirection::PointerAxis axis) const;
0090 
0091     operator libinput_event_pointer *()
0092     {
0093         return m_pointerEvent;
0094     }
0095     operator libinput_event_pointer *() const
0096     {
0097         return m_pointerEvent;
0098     }
0099 
0100 private:
0101     libinput_event_pointer *m_pointerEvent;
0102 };
0103 
0104 class TouchEvent : public Event
0105 {
0106 public:
0107     TouchEvent(libinput_event *event, libinput_event_type type);
0108     ~TouchEvent() override;
0109 
0110     std::chrono::microseconds time() const;
0111     QPointF absolutePos() const;
0112     QPointF absolutePos(const QSize &size) const;
0113     qint32 id() const;
0114 
0115     operator libinput_event_touch *()
0116     {
0117         return m_touchEvent;
0118     }
0119     operator libinput_event_touch *() const
0120     {
0121         return m_touchEvent;
0122     }
0123 
0124 private:
0125     libinput_event_touch *m_touchEvent;
0126 };
0127 
0128 class GestureEvent : public Event
0129 {
0130 public:
0131     ~GestureEvent() override;
0132 
0133     std::chrono::microseconds time() const;
0134     int fingerCount() const;
0135 
0136     QPointF delta() const;
0137 
0138     bool isCancelled() const;
0139 
0140     operator libinput_event_gesture *()
0141     {
0142         return m_gestureEvent;
0143     }
0144     operator libinput_event_gesture *() const
0145     {
0146         return m_gestureEvent;
0147     }
0148 
0149 protected:
0150     GestureEvent(libinput_event *event, libinput_event_type type);
0151     libinput_event_gesture *m_gestureEvent;
0152 };
0153 
0154 class PinchGestureEvent : public GestureEvent
0155 {
0156 public:
0157     PinchGestureEvent(libinput_event *event, libinput_event_type type);
0158     ~PinchGestureEvent() override;
0159 
0160     qreal scale() const;
0161     qreal angleDelta() const;
0162 };
0163 
0164 class SwipeGestureEvent : public GestureEvent
0165 {
0166 public:
0167     SwipeGestureEvent(libinput_event *event, libinput_event_type type);
0168     ~SwipeGestureEvent() override;
0169 };
0170 
0171 class HoldGestureEvent : public GestureEvent
0172 {
0173 public:
0174     HoldGestureEvent(libinput_event *event, libinput_event_type type);
0175     ~HoldGestureEvent() override;
0176 };
0177 
0178 class SwitchEvent : public Event
0179 {
0180 public:
0181     SwitchEvent(libinput_event *event, libinput_event_type type);
0182     ~SwitchEvent() override;
0183 
0184     enum class State {
0185         Off,
0186         On
0187     };
0188     State state() const;
0189 
0190     std::chrono::microseconds time() const;
0191 
0192 private:
0193     libinput_event_switch *m_switchEvent;
0194 };
0195 
0196 class TabletToolEvent : public Event
0197 {
0198 public:
0199     TabletToolEvent(libinput_event *event, libinput_event_type type);
0200 
0201     std::chrono::microseconds time() const
0202     {
0203         return std::chrono::microseconds(libinput_event_tablet_tool_get_time_usec(m_tabletToolEvent));
0204     }
0205     bool xHasChanged() const
0206     {
0207         return libinput_event_tablet_tool_x_has_changed(m_tabletToolEvent);
0208     }
0209     bool yHasChanged() const
0210     {
0211         return libinput_event_tablet_tool_y_has_changed(m_tabletToolEvent);
0212     }
0213     bool pressureHasChanged() const
0214     {
0215         return libinput_event_tablet_tool_pressure_has_changed(m_tabletToolEvent);
0216     }
0217     bool distanceHasChanged() const
0218     {
0219         return libinput_event_tablet_tool_distance_has_changed(m_tabletToolEvent);
0220     }
0221     bool tiltXHasChanged() const
0222     {
0223         return libinput_event_tablet_tool_tilt_x_has_changed(m_tabletToolEvent);
0224     }
0225     bool tiltYHasChanged() const
0226     {
0227         return libinput_event_tablet_tool_tilt_y_has_changed(m_tabletToolEvent);
0228     }
0229     bool rotationHasChanged() const
0230     {
0231         return libinput_event_tablet_tool_rotation_has_changed(m_tabletToolEvent);
0232     }
0233     bool sliderHasChanged() const
0234     {
0235         return libinput_event_tablet_tool_slider_has_changed(m_tabletToolEvent);
0236     }
0237 
0238     // uncomment when depending on libinput 1.14 or when implementing totems
0239     //     bool sizeMajorHasChanged() const { return
0240     //     libinput_event_tablet_tool_size_major_has_changed(m_tabletToolEvent); } bool
0241     //     sizeMinorHasChanged() const { return
0242     //     libinput_event_tablet_tool_size_minor_has_changed(m_tabletToolEvent); }
0243     bool wheelHasChanged() const
0244     {
0245         return libinput_event_tablet_tool_wheel_has_changed(m_tabletToolEvent);
0246     }
0247     QPointF position() const
0248     {
0249         return {libinput_event_tablet_tool_get_x(m_tabletToolEvent),
0250                 libinput_event_tablet_tool_get_y(m_tabletToolEvent)};
0251     }
0252     QPointF delta() const
0253     {
0254         return {libinput_event_tablet_tool_get_dx(m_tabletToolEvent),
0255                 libinput_event_tablet_tool_get_dy(m_tabletToolEvent)};
0256     }
0257     qreal pressure() const
0258     {
0259         return libinput_event_tablet_tool_get_pressure(m_tabletToolEvent);
0260     }
0261     qreal distance() const
0262     {
0263         return libinput_event_tablet_tool_get_distance(m_tabletToolEvent);
0264     }
0265     int xTilt() const
0266     {
0267         return libinput_event_tablet_tool_get_tilt_x(m_tabletToolEvent);
0268     }
0269     int yTilt() const
0270     {
0271         return libinput_event_tablet_tool_get_tilt_y(m_tabletToolEvent);
0272     }
0273     qreal rotation() const
0274     {
0275         return libinput_event_tablet_tool_get_rotation(m_tabletToolEvent);
0276     }
0277     qreal sliderPosition() const
0278     {
0279         return libinput_event_tablet_tool_get_slider_position(m_tabletToolEvent);
0280     }
0281     // Uncomment when depending on libinput 1.14 or when implementing totems
0282     // qreal sizeMajor() const { return
0283     //     libinput_event_tablet_tool_get_size_major(m_tabletToolEvent); }
0284     // qreal sizeMinor() const {
0285     //     return libinput_event_tablet_tool_get_size_minor(m_tabletToolEvent); }
0286     qreal wheelDelta() const
0287     {
0288         return libinput_event_tablet_tool_get_wheel_delta(m_tabletToolEvent);
0289     }
0290     int wheelDeltaDiscrete() const
0291     {
0292         return libinput_event_tablet_tool_get_wheel_delta_discrete(m_tabletToolEvent);
0293     }
0294 
0295     bool isTipDown() const
0296     {
0297         const auto state = libinput_event_tablet_tool_get_tip_state(m_tabletToolEvent);
0298         return state == LIBINPUT_TABLET_TOOL_TIP_DOWN;
0299     }
0300     bool isNearby() const
0301     {
0302         const auto state = libinput_event_tablet_tool_get_proximity_state(m_tabletToolEvent);
0303         return state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN;
0304     }
0305 
0306     QPointF transformedPosition(const QSize &size) const;
0307 
0308     struct libinput_tablet_tool *tool()
0309     {
0310         return libinput_event_tablet_tool_get_tool(m_tabletToolEvent);
0311     }
0312 
0313 private:
0314     libinput_event_tablet_tool *m_tabletToolEvent;
0315 };
0316 
0317 class TabletToolButtonEvent : public Event
0318 {
0319 public:
0320     TabletToolButtonEvent(libinput_event *event, libinput_event_type type);
0321 
0322     uint buttonId() const
0323     {
0324         return libinput_event_tablet_tool_get_button(m_tabletToolEvent);
0325     }
0326 
0327     bool isButtonPressed() const
0328     {
0329         const auto state = libinput_event_tablet_tool_get_button_state(m_tabletToolEvent);
0330         return state == LIBINPUT_BUTTON_STATE_PRESSED;
0331     }
0332 
0333     struct libinput_tablet_tool *tool()
0334     {
0335         return libinput_event_tablet_tool_get_tool(m_tabletToolEvent);
0336     }
0337 
0338     std::chrono::microseconds time() const
0339     {
0340         return std::chrono::microseconds(libinput_event_tablet_tool_get_time_usec(m_tabletToolEvent));
0341     }
0342 
0343 private:
0344     libinput_event_tablet_tool *m_tabletToolEvent;
0345 };
0346 
0347 class TabletPadRingEvent : public Event
0348 {
0349 public:
0350     TabletPadRingEvent(libinput_event *event, libinput_event_type type);
0351 
0352     int position() const
0353     {
0354         return libinput_event_tablet_pad_get_ring_position(m_tabletPadEvent);
0355     }
0356     int number() const
0357     {
0358         return libinput_event_tablet_pad_get_ring_number(m_tabletPadEvent);
0359     }
0360     libinput_tablet_pad_ring_axis_source source() const
0361     {
0362         return libinput_event_tablet_pad_get_ring_source(m_tabletPadEvent);
0363     }
0364     std::chrono::microseconds time() const
0365     {
0366         return std::chrono::microseconds(libinput_event_tablet_pad_get_time_usec(m_tabletPadEvent));
0367     }
0368 
0369 private:
0370     libinput_event_tablet_pad *m_tabletPadEvent;
0371 };
0372 
0373 class TabletPadStripEvent : public Event
0374 {
0375 public:
0376     TabletPadStripEvent(libinput_event *event, libinput_event_type type);
0377 
0378     int position() const
0379     {
0380         return libinput_event_tablet_pad_get_strip_position(m_tabletPadEvent);
0381     }
0382     int number() const
0383     {
0384         return libinput_event_tablet_pad_get_strip_number(m_tabletPadEvent);
0385     }
0386     libinput_tablet_pad_strip_axis_source source() const
0387     {
0388         return libinput_event_tablet_pad_get_strip_source(m_tabletPadEvent);
0389     }
0390     std::chrono::microseconds time() const
0391     {
0392         return std::chrono::microseconds(libinput_event_tablet_pad_get_time_usec(m_tabletPadEvent));
0393     }
0394 
0395 private:
0396     libinput_event_tablet_pad *m_tabletPadEvent;
0397 };
0398 
0399 class TabletPadButtonEvent : public Event
0400 {
0401 public:
0402     TabletPadButtonEvent(libinput_event *event, libinput_event_type type);
0403 
0404     uint buttonId() const
0405     {
0406         return libinput_event_tablet_pad_get_button_number(m_tabletPadEvent);
0407     }
0408     bool isButtonPressed() const
0409     {
0410         const auto state = libinput_event_tablet_pad_get_button_state(m_tabletPadEvent);
0411         return state == LIBINPUT_BUTTON_STATE_PRESSED;
0412     }
0413     std::chrono::microseconds time() const
0414     {
0415         return std::chrono::microseconds(libinput_event_tablet_pad_get_time_usec(m_tabletPadEvent));
0416     }
0417 
0418 private:
0419     libinput_event_tablet_pad *m_tabletPadEvent;
0420 };
0421 
0422 inline libinput_event_type Event::type() const
0423 {
0424     return m_type;
0425 }
0426 
0427 }
0428 }