1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 #ifndef KWIN_LIBINPUT_EVENTS_H
10 #define KWIN_LIBINPUT_EVENTS_H
11 
12 #include "input.h"
13 
14 #include <libinput.h>
15 
16 namespace KWin
17 {
18 namespace LibInput
19 {
20 
21 class Device;
22 
23 class Event
24 {
25 public:
26     virtual ~Event();
27 
28     libinput_event_type type() const;
29     Device *device() const;
30     libinput_device *nativeDevice() const;
31 
32     operator libinput_event*() {
33         return m_event;
34     }
35     operator libinput_event*() const {
36         return m_event;
37     }
38 
39     static Event *create(libinput_event *event);
40 
41 protected:
42     Event(libinput_event *event, libinput_event_type type);
43 
44 private:
45     libinput_event *m_event;
46     libinput_event_type m_type;
47     mutable Device *m_device;
48 };
49 
50 class KeyEvent : public Event
51 {
52 public:
53     KeyEvent(libinput_event *event);
54     ~KeyEvent() override;
55 
56     uint32_t key() const;
57     InputRedirection::KeyboardKeyState state() const;
58     uint32_t time() const;
59 
60     operator libinput_event_keyboard*() {
61         return m_keyboardEvent;
62     }
63     operator libinput_event_keyboard*() const {
64         return m_keyboardEvent;
65     }
66 
67 private:
68     libinput_event_keyboard *m_keyboardEvent;
69 };
70 
71 class PointerEvent : public Event
72 {
73 public:
74     PointerEvent(libinput_event* event, libinput_event_type type);
75     ~PointerEvent() override;
76 
77     QPointF absolutePos() const;
78     QPointF absolutePos(const QSize &size) const;
79     QSizeF delta() const;
80     QSizeF deltaUnaccelerated() const;
81     uint32_t button() const;
82     InputRedirection::PointerButtonState buttonState() const;
83     uint32_t time() const;
84     quint64 timeMicroseconds() const;
85     QVector<InputRedirection::PointerAxis> axis() const;
86     qreal axisValue(InputRedirection::PointerAxis a) const;
87     qint32 discreteAxisValue(InputRedirection::PointerAxis axis) const;
88     InputRedirection::PointerAxisSource axisSource() const;
89 
90     operator libinput_event_pointer*() {
91         return m_pointerEvent;
92     }
93     operator libinput_event_pointer*() const {
94         return m_pointerEvent;
95     }
96 
97 private:
98     libinput_event_pointer *m_pointerEvent;
99 };
100 
101 class TouchEvent : public Event
102 {
103 public:
104     TouchEvent(libinput_event *event, libinput_event_type type);
105     ~TouchEvent() override;
106 
107     quint32 time() const;
108     QPointF absolutePos() const;
109     QPointF absolutePos(const QSize &size) const;
110     qint32 id() const;
111 
112     operator libinput_event_touch*() {
113         return m_touchEvent;
114     }
115     operator libinput_event_touch*() const {
116         return m_touchEvent;
117     }
118 
119 private:
120     libinput_event_touch *m_touchEvent;
121 };
122 
123 class GestureEvent : public Event
124 {
125 public:
126     ~GestureEvent() override;
127 
128     quint32 time() const;
129     int fingerCount() const;
130 
131     QSizeF delta() const;
132 
133     bool isCancelled() const;
134 
135     operator libinput_event_gesture*() {
136         return m_gestureEvent;
137     }
138     operator libinput_event_gesture*() const {
139         return m_gestureEvent;
140     }
141 
142 protected:
143     GestureEvent(libinput_event *event, libinput_event_type type);
144     libinput_event_gesture *m_gestureEvent;
145 };
146 
147 class PinchGestureEvent : public GestureEvent
148 {
149 public:
150     PinchGestureEvent(libinput_event *event, libinput_event_type type);
151     ~PinchGestureEvent() override;
152 
153     qreal scale() const;
154     qreal angleDelta() const;
155 };
156 
157 class SwipeGestureEvent : public GestureEvent
158 {
159 public:
160     SwipeGestureEvent(libinput_event *event, libinput_event_type type);
161     ~SwipeGestureEvent() override;
162 };
163 
164 class SwitchEvent : public Event
165 {
166 public:
167     SwitchEvent(libinput_event *event, libinput_event_type type);
168     ~SwitchEvent() override;
169 
170     enum class State {
171         Off,
172         On
173     };
174     State state() const;
175 
176     quint32 time() const;
177     quint64 timeMicroseconds() const;
178 
179 private:
180     libinput_event_switch *m_switchEvent;
181 };
182 
183 class TabletToolEvent : public Event
184 {
185 public:
186     TabletToolEvent(libinput_event *event, libinput_event_type type);
187 
time()188     uint32_t time() const
189     {
190         return libinput_event_tablet_tool_get_time(m_tabletToolEvent);
191     }
xHasChanged()192     bool xHasChanged() const {
193         return libinput_event_tablet_tool_x_has_changed(m_tabletToolEvent);
194     }
yHasChanged()195     bool yHasChanged() const {
196         return libinput_event_tablet_tool_y_has_changed(m_tabletToolEvent);
197     }
pressureHasChanged()198     bool pressureHasChanged() const {
199         return libinput_event_tablet_tool_pressure_has_changed(m_tabletToolEvent);
200     }
distanceHasChanged()201     bool distanceHasChanged() const {
202         return libinput_event_tablet_tool_distance_has_changed(m_tabletToolEvent);
203     }
tiltXHasChanged()204     bool tiltXHasChanged() const {
205         return libinput_event_tablet_tool_tilt_x_has_changed(m_tabletToolEvent);
206     }
tiltYHasChanged()207     bool tiltYHasChanged() const {
208         return libinput_event_tablet_tool_tilt_y_has_changed(m_tabletToolEvent);
209     }
rotationHasChanged()210     bool rotationHasChanged() const {
211         return libinput_event_tablet_tool_rotation_has_changed(m_tabletToolEvent);
212     }
sliderHasChanged()213     bool sliderHasChanged() const {
214         return libinput_event_tablet_tool_slider_has_changed(m_tabletToolEvent);
215     }
216 
217     // uncomment when depending on libinput 1.14 or when implementing totems
218     //     bool sizeMajorHasChanged() const { return
219     //     libinput_event_tablet_tool_size_major_has_changed(m_tabletToolEvent); } bool
220     //     sizeMinorHasChanged() const { return
221     //     libinput_event_tablet_tool_size_minor_has_changed(m_tabletToolEvent); }
wheelHasChanged()222     bool wheelHasChanged() const {
223         return libinput_event_tablet_tool_wheel_has_changed(m_tabletToolEvent);
224     }
position()225     QPointF position() const {
226         return {libinput_event_tablet_tool_get_x(m_tabletToolEvent),
227                 libinput_event_tablet_tool_get_y(m_tabletToolEvent)};
228     }
delta()229     QPointF delta() const {
230         return {libinput_event_tablet_tool_get_dx(m_tabletToolEvent),
231                 libinput_event_tablet_tool_get_dy(m_tabletToolEvent)};
232     }
pressure()233     qreal pressure() const {
234         return libinput_event_tablet_tool_get_pressure(m_tabletToolEvent);
235     }
distance()236     qreal distance() const {
237         return libinput_event_tablet_tool_get_distance(m_tabletToolEvent);
238     }
xTilt()239     int xTilt() const {
240         return libinput_event_tablet_tool_get_tilt_x(m_tabletToolEvent);
241     }
yTilt()242     int yTilt() const {
243         return libinput_event_tablet_tool_get_tilt_y(m_tabletToolEvent);
244     }
rotation()245     qreal rotation() const {
246         return libinput_event_tablet_tool_get_rotation(m_tabletToolEvent);
247     }
sliderPosition()248     qreal sliderPosition() const {
249         return libinput_event_tablet_tool_get_slider_position(m_tabletToolEvent);
250     }
251     // Uncomment when depending on libinput 1.14 or when implementing totems
252     // qreal sizeMajor() const { return
253     //     libinput_event_tablet_tool_get_size_major(m_tabletToolEvent); }
254     // qreal sizeMinor() const {
255     //     return libinput_event_tablet_tool_get_size_minor(m_tabletToolEvent); }
wheelDelta()256     qreal wheelDelta() const {
257         return libinput_event_tablet_tool_get_wheel_delta(m_tabletToolEvent);
258     }
wheelDeltaDiscrete()259     int wheelDeltaDiscrete() const {
260         return libinput_event_tablet_tool_get_wheel_delta_discrete(m_tabletToolEvent);
261     }
262 
isTipDown()263     bool isTipDown() const {
264         const auto state = libinput_event_tablet_tool_get_tip_state(m_tabletToolEvent);
265         return state == LIBINPUT_TABLET_TOOL_TIP_DOWN;
266     }
isNearby()267     bool isNearby() const {
268         const auto state = libinput_event_tablet_tool_get_proximity_state(m_tabletToolEvent);
269         return state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN;
270     }
271 
transformedPosition(const QSize & size)272     QPointF transformedPosition(const QSize &size) const {
273         return {libinput_event_tablet_tool_get_x_transformed(m_tabletToolEvent, size.width()),
274                 libinput_event_tablet_tool_get_y_transformed(m_tabletToolEvent, size.height())};
275     }
276 
tool()277     struct libinput_tablet_tool *tool() {
278         return libinput_event_tablet_tool_get_tool(m_tabletToolEvent);
279     }
280 
281 private:
282     libinput_event_tablet_tool *m_tabletToolEvent;
283 };
284 
285 class TabletToolButtonEvent : public Event
286 {
287 public:
288     TabletToolButtonEvent(libinput_event *event, libinput_event_type type);
289 
buttonId()290     uint buttonId() const {
291         return libinput_event_tablet_tool_get_button(m_tabletToolEvent);
292     }
293 
isButtonPressed()294     bool isButtonPressed() const {
295         const auto state = libinput_event_tablet_tool_get_button_state(m_tabletToolEvent);
296         return state == LIBINPUT_BUTTON_STATE_PRESSED;
297     }
298 
tool()299     struct libinput_tablet_tool *tool() {
300         return libinput_event_tablet_tool_get_tool(m_tabletToolEvent);
301     }
302 
303 private:
304     libinput_event_tablet_tool *m_tabletToolEvent;
305 };
306 
307 class TabletPadRingEvent : public Event
308 {
309 public:
310     TabletPadRingEvent(libinput_event *event, libinput_event_type type);
311 
position()312     int position() const {
313         return libinput_event_tablet_pad_get_ring_position(m_tabletPadEvent);
314     }
number()315     int number() const {
316         return libinput_event_tablet_pad_get_ring_number(m_tabletPadEvent);
317     }
source()318     libinput_tablet_pad_ring_axis_source source() const {
319         return libinput_event_tablet_pad_get_ring_source(m_tabletPadEvent);
320     }
321 
322 private:
323     libinput_event_tablet_pad *m_tabletPadEvent;
324 };
325 
326 class TabletPadStripEvent : public Event
327 {
328 public:
329     TabletPadStripEvent(libinput_event *event, libinput_event_type type);
330 
position()331     int position() const {
332         return libinput_event_tablet_pad_get_strip_position(m_tabletPadEvent);
333     }
number()334     int number() const {
335         return libinput_event_tablet_pad_get_strip_number(m_tabletPadEvent);
336     }
source()337     libinput_tablet_pad_strip_axis_source source() const {
338         return libinput_event_tablet_pad_get_strip_source(m_tabletPadEvent);
339     }
340 
341 private:
342     libinput_event_tablet_pad *m_tabletPadEvent;
343 };
344 
345 class TabletPadButtonEvent : public Event
346 {
347 public:
348     TabletPadButtonEvent(libinput_event *event, libinput_event_type type);
349 
buttonId()350     uint buttonId() const {
351         return libinput_event_tablet_pad_get_button_number(m_tabletPadEvent);
352     }
isButtonPressed()353     bool isButtonPressed() const {
354         const auto state = libinput_event_tablet_pad_get_button_state(m_tabletPadEvent);
355         return state == LIBINPUT_BUTTON_STATE_PRESSED;
356     }
357 
358 private:
359     libinput_event_tablet_pad *m_tabletPadEvent;
360 };
361 
362 inline
type()363 libinput_event_type Event::type() const
364 {
365     return m_type;
366 }
367 
368 }
369 }
370 
371 #endif
372