File indexing completed on 2024-12-22 05:09:20

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #ifndef WAYLAND_EVENT_QUEUE_H
0007 #define WAYLAND_EVENT_QUEUE_H
0008 
0009 #include <QObject>
0010 
0011 #include "KWayland/Client/kwaylandclient_export.h"
0012 
0013 struct wl_display;
0014 struct wl_proxy;
0015 struct wl_event_queue;
0016 
0017 namespace KWayland
0018 {
0019 namespace Client
0020 {
0021 class ConnectionThread;
0022 
0023 /**
0024  * @short Wrapper class for wl_event_queue interface.
0025  *
0026  * The EventQueue is needed if a different thread is used for the connection.
0027  * If the interface wrappers are held in a different thread than the connection thread
0028  * an EventQueue is needed for the thread which holds the interface wrappers. A common
0029  * example is a dedicated connection thread while the interface wrappers are created
0030  * in the main thread.
0031  *
0032  * All interface wrappers are set up to support the EventQueue in the most convenient
0033  * way. The EventQueue needs only to be passed to the Registry. The EventQueue will then
0034  * be passed to all created wrappers through the tree.
0035  *
0036  * @code
0037  * ConnectionThread connection;
0038  * EventQueue queue;
0039  * Registry registry;
0040  *
0041  * connect(&connection, &ConnectionThread::connected, this, [&] {
0042  *     queue.setup(&connection);
0043  *     registry.setEventQueue(&queue);
0044  *     registry.setup(&connection);
0045  *     registry.create();
0046  * });
0047  *
0048  * connection.initConnection();
0049  * @endcode
0050  *
0051  * The EventQueue can be used as a drop-in replacement for any wl_event_queue
0052  * pointer as it provides matching cast operators.
0053  **/
0054 class KWAYLANDCLIENT_EXPORT EventQueue : public QObject
0055 {
0056     Q_OBJECT
0057 public:
0058     explicit EventQueue(QObject *parent = nullptr);
0059     ~EventQueue() override;
0060 
0061     /**
0062      * Creates the event queue for the @p display.
0063      *
0064      * Note: this will not automatically setup the dispatcher.
0065      * When using this method one needs to ensure that dispatch
0066      * gets invoked whenever new events need to be dispatched.
0067      * @see dispatch
0068      **/
0069     void setup(wl_display *display);
0070     /**
0071      * Creates the event queue for the @p connection.
0072      *
0073      * This method also connects the eventsRead signal of the ConnectionThread
0074      * to the dispatch method. Events will be automatically dispatched without
0075      * the need to call dispatch manually.
0076      * @see dispatch
0077      **/
0078     void setup(ConnectionThread *connection);
0079 
0080     /**
0081      * @returns @c true if EventQueue is setup.
0082      **/
0083     bool isValid();
0084     /**
0085      * Releases the wl_event_queue interface.
0086      * After the interface has been released the EventQueue instance is no
0087      * longer valid and can be setup with another wl_event_queue interface.
0088      **/
0089     void release();
0090     /**
0091      * Destroys the data held by this EventQueue.
0092      * This method is supposed to be used when the connection to the Wayland
0093      * server goes away. If the connection is not valid anymore, it's not
0094      * possible to call release anymore as that calls into the Wayland
0095      * connection and the call would fail. This method cleans up the data, so
0096      * that the instance can be deleted or set up to a new wl_event_queue interface
0097      * once there is a new connection available.
0098      *
0099      * @see release
0100      **/
0101     void destroy();
0102 
0103     /**
0104      * Adds the @p proxy to the EventQueue.
0105      **/
0106     void addProxy(wl_proxy *proxy);
0107     /**
0108      * Adds the @p proxy of type wl_interface (e.g. wl_compositor) to the EventQueue.
0109      **/
0110     template<typename wl_interface>
0111     void addProxy(wl_interface *proxy);
0112     /**
0113      * Adds the @p proxy wrapper class of type T referencing the wl_interface to the EventQueue.
0114      **/
0115     template<typename wl_interface, typename T>
0116     void addProxy(T *proxy);
0117 
0118     operator wl_event_queue *();
0119     operator wl_event_queue *() const;
0120 
0121 public Q_SLOTS:
0122     /**
0123      * Dispatches all pending events on the EventQueue.
0124      **/
0125     void dispatch();
0126 
0127 private:
0128     class Private;
0129     QScopedPointer<Private> d;
0130 };
0131 
0132 template<typename wl_interface>
0133 inline void EventQueue::addProxy(wl_interface *proxy)
0134 {
0135     addProxy(reinterpret_cast<wl_proxy *>(proxy));
0136 }
0137 
0138 template<typename wl_interface, typename T>
0139 inline void EventQueue::addProxy(T *proxy)
0140 {
0141     addProxy(reinterpret_cast<wl_proxy *>((wl_interface *)*(proxy)));
0142 }
0143 
0144 }
0145 }
0146 
0147 #endif