1 | /* |
2 | SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
5 | */ |
6 | #ifndef WAYLAND_EVENT_QUEUE_H |
7 | #define WAYLAND_EVENT_QUEUE_H |
8 | |
9 | #include <QObject> |
10 | |
11 | #include "KWayland/Client/kwaylandclient_export.h" |
12 | |
13 | struct wl_display; |
14 | struct wl_proxy; |
15 | struct wl_event_queue; |
16 | |
17 | namespace KWayland |
18 | { |
19 | namespace Client |
20 | { |
21 | class ConnectionThread; |
22 | |
23 | /** |
24 | * @short Wrapper class for wl_event_queue interface. |
25 | * |
26 | * The EventQueue is needed if a different thread is used for the connection. |
27 | * If the interface wrappers are held in a different thread than the connection thread |
28 | * an EventQueue is needed for the thread which holds the interface wrappers. A common |
29 | * example is a dedicated connection thread while the interface wrappers are created |
30 | * in the main thread. |
31 | * |
32 | * All interface wrappers are set up to support the EventQueue in the most convenient |
33 | * way. The EventQueue needs only to be passed to the Registry. The EventQueue will then |
34 | * be passed to all created wrappers through the tree. |
35 | * |
36 | * @code |
37 | * ConnectionThread connection; |
38 | * EventQueue queue; |
39 | * Registry registry; |
40 | * |
41 | * connect(&connection, &ConnectionThread::connected, this, [&] { |
42 | * queue.setup(&connection); |
43 | * registry.setEventQueue(&queue); |
44 | * registry.setup(&connection); |
45 | * registry.create(); |
46 | * }); |
47 | * |
48 | * connection.initConnection(); |
49 | * @endcode |
50 | * |
51 | * The EventQueue can be used as a drop-in replacement for any wl_event_queue |
52 | * pointer as it provides matching cast operators. |
53 | **/ |
54 | class KWAYLANDCLIENT_EXPORT EventQueue : public QObject |
55 | { |
56 | Q_OBJECT |
57 | public: |
58 | explicit EventQueue(QObject *parent = nullptr); |
59 | ~EventQueue() override; |
60 | |
61 | /** |
62 | * Creates the event queue for the @p display. |
63 | * |
64 | * Note: this will not automatically setup the dispatcher. |
65 | * When using this method one needs to ensure that dispatch |
66 | * gets invoked whenever new events need to be dispatched. |
67 | * @see dispatch |
68 | **/ |
69 | void setup(wl_display *display); |
70 | /** |
71 | * Creates the event queue for the @p connection. |
72 | * |
73 | * This method also connects the eventsRead signal of the ConnectionThread |
74 | * to the dispatch method. Events will be automatically dispatched without |
75 | * the need to call dispatch manually. |
76 | * @see dispatch |
77 | **/ |
78 | void setup(ConnectionThread *connection); |
79 | |
80 | /** |
81 | * @returns @c true if EventQueue is setup. |
82 | **/ |
83 | bool isValid(); |
84 | /** |
85 | * Releases the wl_event_queue interface. |
86 | * After the interface has been released the EventQueue instance is no |
87 | * longer valid and can be setup with another wl_event_queue interface. |
88 | **/ |
89 | void release(); |
90 | /** |
91 | * Destroys the data held by this EventQueue. |
92 | * This method is supposed to be used when the connection to the Wayland |
93 | * server goes away. If the connection is not valid anymore, it's not |
94 | * possible to call release anymore as that calls into the Wayland |
95 | * connection and the call would fail. This method cleans up the data, so |
96 | * that the instance can be deleted or set up to a new wl_event_queue interface |
97 | * once there is a new connection available. |
98 | * |
99 | * @see release |
100 | **/ |
101 | void destroy(); |
102 | |
103 | /** |
104 | * Adds the @p proxy to the EventQueue. |
105 | **/ |
106 | void addProxy(wl_proxy *proxy); |
107 | /** |
108 | * Adds the @p proxy of type wl_interface (e.g. wl_compositor) to the EventQueue. |
109 | **/ |
110 | template<typename wl_interface> |
111 | void addProxy(wl_interface *proxy); |
112 | /** |
113 | * Adds the @p proxy wrapper class of type T referencing the wl_interface to the EventQueue. |
114 | **/ |
115 | template<typename wl_interface, typename T> |
116 | void addProxy(T *proxy); |
117 | |
118 | operator wl_event_queue *(); |
119 | operator wl_event_queue *() const; |
120 | |
121 | public Q_SLOTS: |
122 | /** |
123 | * Dispatches all pending events on the EventQueue. |
124 | **/ |
125 | void dispatch(); |
126 | |
127 | private: |
128 | class Private; |
129 | QScopedPointer<Private> d; |
130 | }; |
131 | |
132 | template<typename wl_interface> |
133 | inline void EventQueue::addProxy(wl_interface *proxy) |
134 | { |
135 | addProxy(proxy: reinterpret_cast<wl_proxy *>(proxy)); |
136 | } |
137 | |
138 | template<typename wl_interface, typename T> |
139 | inline void EventQueue::addProxy(T *proxy) |
140 | { |
141 | addProxy(proxy: reinterpret_cast<wl_proxy *>((wl_interface *)*(proxy))); |
142 | } |
143 | |
144 | } |
145 | } |
146 | |
147 | #endif |
148 | |