Wayland++  1.0.0
C++ Bindings for Wayland
wayland-client.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2022, Nils Christopher Brause, Philipp Kerling
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef WAYLAND_CLIENT_HPP
27 #define WAYLAND_CLIENT_HPP
28 
31 #include <atomic>
32 #include <cstdint>
33 #include <functional>
34 #include <memory>
35 #include <string>
36 #include <vector>
37 #include <wayland-version.hpp>
38 #include <wayland-client-core.h>
39 #include <wayland-util.hpp>
40 
41 namespace wayland
42 {
47  using log_handler = std::function<void(std::string)> ;
48 
58 
64  class event_queue_t : public detail::refcounted_wrapper<wl_event_queue>
65  {
66  event_queue_t(wl_event_queue *q);
67  friend class display_t;
68  public:
69  event_queue_t() = default;
70  event_queue_t(const event_queue_t&) = default;
71  event_queue_t(event_queue_t&&) noexcept = default;
72  event_queue_t& operator=(const event_queue_t&) = default;
73  event_queue_t& operator=(event_queue_t&&) noexcept = default;
74  ~event_queue_t() noexcept = default;
75  };
76 
77  class display_t;
78 
79  namespace detail
80  {
81  struct proxy_data_t;
82  // base class for event listener storage.
83  struct events_base_t
84  {
85  events_base_t() = default;
86  events_base_t(const events_base_t&) = default;
87  events_base_t(events_base_t&&) noexcept = default;
88  events_base_t& operator=(const events_base_t&) = default;
89  events_base_t& operator=(events_base_t&&) noexcept = default;
90  virtual ~events_base_t() noexcept = default;
91  };
92  }
93 
109  class proxy_t
110  {
111  public:
116  enum class wrapper_type
117  {
122  standard,
127  display,
137  foreign,
145  proxy_wrapper
146  };
147 
148  private:
149  wl_proxy *proxy = nullptr;
150  detail::proxy_data_t *data = nullptr;
151  wrapper_type type = wrapper_type::standard;
152  friend class detail::argument_t;
153  friend struct detail::proxy_data_t;
154 
155  // Interface desctiption filled in by the each interface class
156  const wl_interface *interface = nullptr;
157 
158  // copy constructor filled in by the each interface class
159  std::function<proxy_t(proxy_t)> copy_constructor;
160 
161  // universal dispatcher
162  static int c_dispatcher(const void *implementation, void *target,
163  uint32_t opcode, const wl_message *message,
164  wl_argument *args);
165 
166  // marshal request
167  proxy_t marshal_single(uint32_t opcode, const wl_interface *interface,
168  const std::vector<detail::argument_t>& args, std::uint32_t version = 0);
169 
170  protected:
171  void set_interface(const wl_interface *iface);
172  void set_copy_constructor(const std::function<proxy_t(proxy_t)>& func);
173 
174  friend class registry_t;
175  // marshal a request, that doesn't lead a new proxy
176  // Valid types for args are:
177  // - uint32_t
178  // - int32_t
179  // - proxy_t
180  // - std::string
181  // - array_t
182  template <typename...T>
183  void marshal(uint32_t opcode, const T& ...args)
184  {
185  std::vector<detail::argument_t> v = { detail::argument_t(args)... };
186  marshal_single(opcode, nullptr, v);
187  }
188 
189  // marshal a request that leads to a new proxy with inherited version
190  template <typename...T>
191  proxy_t marshal_constructor(uint32_t opcode, const wl_interface *interface,
192  const T& ...args)
193  {
194  std::vector<detail::argument_t> v = { detail::argument_t(args)... };
195  return marshal_single(opcode, interface, v);
196  }
197 
198  // marshal a request that leads to a new proxy with specific version
199  template <typename...T>
200  proxy_t marshal_constructor_versioned(uint32_t opcode, const wl_interface *interface,
201  uint32_t version, const T& ...args)
202  {
203  std::vector<detail::argument_t> v = { detail::argument_t(args)... };
204  return marshal_single(opcode, interface, v, version);
205  }
206 
207  // Set the opcode for destruction of the proxy
208  void set_destroy_opcode(uint32_t destroy_opcode);
209 
210  /*
211  Sets the dispatcher and its user data. User data must be an
212  instance of a class derived from events_base_t, allocated with
213  new. Will automatically be deleted upon destruction.
214  */
215  void set_events(std::shared_ptr<detail::events_base_t> events,
216  int(*dispatcher)(uint32_t, const std::vector<detail::any>&, const std::shared_ptr<detail::events_base_t>&));
217 
218  // Retrieve the previously set user data
219  std::shared_ptr<detail::events_base_t> get_events();
220 
221  // Constructs NULL proxies.
222  proxy_t() = default;
223 
224  struct construct_proxy_wrapper_tag {};
225  // Construct from proxy as wrapper
226  proxy_t(const proxy_t &wrapped_proxy, construct_proxy_wrapper_tag /*unused*/);
227 
228  public:
234  proxy_t(wl_proxy *p, wrapper_type t = wrapper_type::standard, event_queue_t const& queue = event_queue_t());
235 
241  proxy_t(const proxy_t &p);
242 
249 
256  proxy_t(proxy_t &&p) noexcept;
257 
263  proxy_t &operator=(proxy_t &&p) noexcept;
264 
275 
279  uint32_t get_id() const;
280 
284  std::string get_class() const;
285 
298  uint32_t get_version() const;
299 
303  {
304  return type;
305  }
306 
316 
321  wl_proxy *c_ptr() const;
322 
327  bool proxy_has_object() const;
328 
333  operator bool() const;
334 
337  bool operator==(const proxy_t &right) const;
338 
341  bool operator!=(const proxy_t &right) const;
342 
349  };
350 
372  {
373  public:
374  read_intent(read_intent &&other) noexcept = default;
375  read_intent(read_intent const &other) = delete;
376  read_intent& operator=(read_intent const &other) = delete;
377  read_intent& operator=(read_intent &&other) noexcept = delete;
378  ~read_intent();
379 
383  bool is_finalized() const;
384 
389  void cancel();
390 
404  void read();
405 
406  private:
407  read_intent(wl_display *display, wl_event_queue *event_queue = nullptr);
408  friend class display_t;
409 
410  wl_display *display;
411  wl_event_queue *event_queue = nullptr;
412  bool finalized = false;
413  };
414 
415  class callback_t;
416  class registry_t;
417 
478  class display_t : public proxy_t
479  {
480  private:
481  // Construct as proxy wrapper
482  display_t(proxy_t const &wrapped_proxy, construct_proxy_wrapper_tag /*unused*/);
483 
484  public:
492  display_t(int fd);
493 
494  display_t(display_t &&d) noexcept;
495  display_t(const display_t &d) = delete;
496  display_t &operator=(const display_t &d) = delete;
497  display_t &operator=(display_t &&d) noexcept;
498 
507  display_t(const std::string& name = {});
508 
531  explicit display_t(wl_display* display);
532 
540  ~display_t() noexcept = default;
541 
546  event_queue_t create_queue() const;
547 
554  int get_fd() const;
555 
563  int roundtrip() const;
564 
577  int roundtrip_queue(const event_queue_t& queue) const;
578 
611  read_intent obtain_read_intent() const;
612 
622  read_intent obtain_queue_read_intent(const event_queue_t& queue) const;
623 
638  int dispatch_queue(const event_queue_t& queue) const;
639 
650  int dispatch_queue_pending(const event_queue_t& queue) const;
651 
672  int dispatch() const;
673 
710  int dispatch_pending() const;
711 
722  int get_error() const;
723 
738  std::tuple<int, bool> flush() const;
739 
752  callback_t sync();
753 
759  registry_t get_registry();
760 
761  operator wl_display*() const;
762 
765  display_t proxy_create_wrapper();
766  };
767 }
768 
769 #include <wayland-client-protocol.hpp>
770 
771 #endif
Refcounted wrapper for C objects.
Represents a connection to the compositor and acts as a proxy to the display singleton object.
~display_t() noexcept=default
Close a connection to a Wayland display.
display_t(const std::string &name={})
Connect to a Wayland display.
display_t(int fd)
Connect to Wayland display on an already open fd.
display_t(wl_display *display)
Use an existing connection to a Wayland display to construct a waylandpp display_t.
A queue for proxy_t object events.
Represents a protocol object on the client side.
void proxy_release()
Release the wrapped object (if any), making this an empty wrapper.
bool proxy_has_object() const
Check whether this wrapper actually wraps an object.
void set_queue(event_queue_t queue)
Assign a proxy to an event queue.
uint32_t get_id() const
Get the id of a proxy object.
bool operator==(const proxy_t &right) const
Check whether two wrappers refer to the same object.
~proxy_t()
Destructor.
proxy_t(const proxy_t &p)
Copy Constructior.
uint32_t get_version() const
Get the protocol object version of a proxy object.
wrapper_type get_wrapper_type() const
Get the type of a proxy object.
wl_proxy * c_ptr() const
Get a pointer to the underlying C struct.
proxy_t & operator=(proxy_t &&p) noexcept
Move Asignment operator.
std::string get_class() const
Get the interface name (class) of a proxy object.
proxy_t(proxy_t &&p) noexcept
Move Constructior.
bool operator!=(const proxy_t &right) const
Check whether two wrappers refer to different objects.
proxy_t(wl_proxy *p, wrapper_type t=wrapper_type::standard, event_queue_t const &queue=event_queue_t())
Cronstruct a proxy_t from a wl_proxy pointer.
proxy_t & operator=(const proxy_t &p)
Assignment operator.
Represents an intention to read from the display file descriptor.
void cancel()
Cancel read intent.
bool is_finalized() const
Check whether this intent was already finalized with cancel or read.
void read()
Read events from display file descriptor.
global registry object
std::function< void(std::string)> log_handler
Type for functions that handle log messages.
void set_log_handler(log_handler handler)
Set C library log handler.