#pragma once

#include <array>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <vector>

#include <wayland-server.hpp>
#include <wayland-server-protocol-extra.hpp>

struct zwp_fullscreen_shell_v1;
struct zwp_fullscreen_shell_mode_feedback_v1;
struct zwp_idle_inhibit_manager_v1;
struct zwp_idle_inhibitor_v1;
struct zwp_input_method_context_v1;
struct zwp_input_method_v1;
struct zwp_input_panel_v1;
struct zwp_input_panel_surface_v1;
struct zwp_input_timestamps_manager_v1;
struct zwp_input_timestamps_v1;
struct zwp_keyboard_shortcuts_inhibit_manager_v1;
struct zwp_keyboard_shortcuts_inhibitor_v1;
struct zwp_linux_dmabuf_v1;
struct zwp_linux_buffer_params_v1;
struct zwp_linux_dmabuf_feedback_v1;
struct zwp_linux_explicit_synchronization_v1;
struct zwp_linux_surface_synchronization_v1;
struct zwp_linux_buffer_release_v1;
struct zwp_pointer_constraints_v1;
struct zwp_locked_pointer_v1;
struct zwp_confined_pointer_v1;
struct zwp_pointer_gestures_v1;
struct zwp_pointer_gesture_swipe_v1;
struct zwp_pointer_gesture_pinch_v1;
struct zwp_pointer_gesture_hold_v1;
struct zwp_primary_selection_device_manager_v1;
struct zwp_primary_selection_device_v1;
struct zwp_primary_selection_offer_v1;
struct zwp_primary_selection_source_v1;
struct zwp_relative_pointer_manager_v1;
struct zwp_relative_pointer_v1;
struct zwp_tablet_manager_v1;
struct zwp_tablet_seat_v1;
struct zwp_tablet_tool_v1;
struct zwp_tablet_v1;
struct zwp_tablet_manager_v2;
struct zwp_tablet_seat_v2;
struct zwp_tablet_tool_v2;
struct zwp_tablet_v2;
struct zwp_tablet_pad_ring_v2;
struct zwp_tablet_pad_strip_v2;
struct zwp_tablet_pad_group_v2;
struct zwp_tablet_pad_v2;
struct zwp_text_input_v1;
struct zwp_text_input_manager_v1;
struct zwp_text_input_v3;
struct zwp_text_input_manager_v3;
struct xdg_activation_v1;
struct xdg_activation_token_v1;
struct zxdg_decoration_manager_v1;
struct zxdg_toplevel_decoration_v1;
struct zxdg_exporter_v1;
struct zxdg_importer_v1;
struct zxdg_exported_v1;
struct zxdg_imported_v1;
struct zxdg_exporter_v2;
struct zxdg_importer_v2;
struct zxdg_exported_v2;
struct zxdg_imported_v2;
struct zxdg_output_manager_v1;
struct zxdg_output_v1;
struct zxdg_shell_v6;
struct zxdg_positioner_v6;
struct zxdg_surface_v6;
struct zxdg_toplevel_v6;
struct zxdg_popup_v6;
struct zwp_xwayland_keyboard_grab_manager_v1;
struct zwp_xwayland_keyboard_grab_v1;

namespace wayland
{
namespace server
{
class zwp_fullscreen_shell_v1_t;
enum class zwp_fullscreen_shell_v1_capability : uint32_t;
enum class zwp_fullscreen_shell_v1_present_method : uint32_t;
enum class zwp_fullscreen_shell_v1_error : uint32_t;
class zwp_fullscreen_shell_mode_feedback_v1_t;
class zwp_idle_inhibit_manager_v1_t;
class zwp_idle_inhibitor_v1_t;
class zwp_input_method_context_v1_t;
class zwp_input_method_v1_t;
class zwp_input_panel_v1_t;
class zwp_input_panel_surface_v1_t;
enum class zwp_input_panel_surface_v1_position : uint32_t;
class zwp_input_timestamps_manager_v1_t;
class zwp_input_timestamps_v1_t;
class zwp_keyboard_shortcuts_inhibit_manager_v1_t;
enum class zwp_keyboard_shortcuts_inhibit_manager_v1_error : uint32_t;
class zwp_keyboard_shortcuts_inhibitor_v1_t;
class zwp_linux_dmabuf_v1_t;
class zwp_linux_buffer_params_v1_t;
enum class zwp_linux_buffer_params_v1_error : uint32_t;
struct zwp_linux_buffer_params_v1_flags;
class zwp_linux_dmabuf_feedback_v1_t;
struct zwp_linux_dmabuf_feedback_v1_tranche_flags;
class zwp_linux_explicit_synchronization_v1_t;
enum class zwp_linux_explicit_synchronization_v1_error : uint32_t;
class zwp_linux_surface_synchronization_v1_t;
enum class zwp_linux_surface_synchronization_v1_error : uint32_t;
class zwp_linux_buffer_release_v1_t;
class zwp_pointer_constraints_v1_t;
enum class zwp_pointer_constraints_v1_error : uint32_t;
enum class zwp_pointer_constraints_v1_lifetime : uint32_t;
class zwp_locked_pointer_v1_t;
class zwp_confined_pointer_v1_t;
class zwp_pointer_gestures_v1_t;
class zwp_pointer_gesture_swipe_v1_t;
class zwp_pointer_gesture_pinch_v1_t;
class zwp_pointer_gesture_hold_v1_t;
class zwp_primary_selection_device_manager_v1_t;
class zwp_primary_selection_device_v1_t;
class zwp_primary_selection_offer_v1_t;
class zwp_primary_selection_source_v1_t;
class zwp_relative_pointer_manager_v1_t;
class zwp_relative_pointer_v1_t;
class zwp_tablet_manager_v1_t;
class zwp_tablet_seat_v1_t;
class zwp_tablet_tool_v1_t;
enum class zwp_tablet_tool_v1_type : uint32_t;
enum class zwp_tablet_tool_v1_capability : uint32_t;
enum class zwp_tablet_tool_v1_button_state : uint32_t;
enum class zwp_tablet_tool_v1_error : uint32_t;
class zwp_tablet_v1_t;
class zwp_tablet_manager_v2_t;
class zwp_tablet_seat_v2_t;
class zwp_tablet_tool_v2_t;
enum class zwp_tablet_tool_v2_type : uint32_t;
enum class zwp_tablet_tool_v2_capability : uint32_t;
enum class zwp_tablet_tool_v2_button_state : uint32_t;
enum class zwp_tablet_tool_v2_error : uint32_t;
class zwp_tablet_v2_t;
class zwp_tablet_pad_ring_v2_t;
enum class zwp_tablet_pad_ring_v2_source : uint32_t;
class zwp_tablet_pad_strip_v2_t;
enum class zwp_tablet_pad_strip_v2_source : uint32_t;
class zwp_tablet_pad_group_v2_t;
class zwp_tablet_pad_v2_t;
enum class zwp_tablet_pad_v2_button_state : uint32_t;
class zwp_text_input_v1_t;
struct zwp_text_input_v1_content_hint;
enum class zwp_text_input_v1_content_purpose : uint32_t;
enum class zwp_text_input_v1_preedit_style : uint32_t;
enum class zwp_text_input_v1_text_direction : uint32_t;
class zwp_text_input_manager_v1_t;
class zwp_text_input_v3_t;
enum class zwp_text_input_v3_change_cause : uint32_t;
struct zwp_text_input_v3_content_hint;
enum class zwp_text_input_v3_content_purpose : uint32_t;
class zwp_text_input_manager_v3_t;
class xdg_activation_v1_t;
class xdg_activation_token_v1_t;
enum class xdg_activation_token_v1_error : uint32_t;
class zxdg_decoration_manager_v1_t;
class zxdg_toplevel_decoration_v1_t;
enum class zxdg_toplevel_decoration_v1_error : uint32_t;
enum class zxdg_toplevel_decoration_v1_mode : uint32_t;
class zxdg_exporter_v1_t;
class zxdg_importer_v1_t;
class zxdg_exported_v1_t;
class zxdg_imported_v1_t;
class zxdg_exporter_v2_t;
enum class zxdg_exporter_v2_error : uint32_t;
class zxdg_importer_v2_t;
class zxdg_exported_v2_t;
class zxdg_imported_v2_t;
enum class zxdg_imported_v2_error : uint32_t;
class zxdg_output_manager_v1_t;
class zxdg_output_v1_t;
class zxdg_shell_v6_t;
enum class zxdg_shell_v6_error : uint32_t;
class zxdg_positioner_v6_t;
enum class zxdg_positioner_v6_error : uint32_t;
struct zxdg_positioner_v6_anchor;
struct zxdg_positioner_v6_gravity;
struct zxdg_positioner_v6_constraint_adjustment;
class zxdg_surface_v6_t;
enum class zxdg_surface_v6_error : uint32_t;
class zxdg_toplevel_v6_t;
struct zxdg_toplevel_v6_resize_edge;
enum class zxdg_toplevel_v6_state : uint32_t;
class zxdg_popup_v6_t;
enum class zxdg_popup_v6_error : uint32_t;
class zwp_xwayland_keyboard_grab_manager_v1_t;
class zwp_xwayland_keyboard_grab_v1_t;

namespace detail
{
  extern const wl_interface zwp_fullscreen_shell_v1_interface;
  extern const wl_interface zwp_fullscreen_shell_mode_feedback_v1_interface;
  extern const wl_interface zwp_idle_inhibit_manager_v1_interface;
  extern const wl_interface zwp_idle_inhibitor_v1_interface;
  extern const wl_interface zwp_input_method_context_v1_interface;
  extern const wl_interface zwp_input_method_v1_interface;
  extern const wl_interface zwp_input_panel_v1_interface;
  extern const wl_interface zwp_input_panel_surface_v1_interface;
  extern const wl_interface zwp_input_timestamps_manager_v1_interface;
  extern const wl_interface zwp_input_timestamps_v1_interface;
  extern const wl_interface zwp_keyboard_shortcuts_inhibit_manager_v1_interface;
  extern const wl_interface zwp_keyboard_shortcuts_inhibitor_v1_interface;
  extern const wl_interface zwp_linux_dmabuf_v1_interface;
  extern const wl_interface zwp_linux_buffer_params_v1_interface;
  extern const wl_interface zwp_linux_dmabuf_feedback_v1_interface;
  extern const wl_interface zwp_linux_explicit_synchronization_v1_interface;
  extern const wl_interface zwp_linux_surface_synchronization_v1_interface;
  extern const wl_interface zwp_linux_buffer_release_v1_interface;
  extern const wl_interface zwp_pointer_constraints_v1_interface;
  extern const wl_interface zwp_locked_pointer_v1_interface;
  extern const wl_interface zwp_confined_pointer_v1_interface;
  extern const wl_interface zwp_pointer_gestures_v1_interface;
  extern const wl_interface zwp_pointer_gesture_swipe_v1_interface;
  extern const wl_interface zwp_pointer_gesture_pinch_v1_interface;
  extern const wl_interface zwp_pointer_gesture_hold_v1_interface;
  extern const wl_interface zwp_primary_selection_device_manager_v1_interface;
  extern const wl_interface zwp_primary_selection_device_v1_interface;
  extern const wl_interface zwp_primary_selection_offer_v1_interface;
  extern const wl_interface zwp_primary_selection_source_v1_interface;
  extern const wl_interface zwp_relative_pointer_manager_v1_interface;
  extern const wl_interface zwp_relative_pointer_v1_interface;
  extern const wl_interface zwp_tablet_manager_v1_interface;
  extern const wl_interface zwp_tablet_seat_v1_interface;
  extern const wl_interface zwp_tablet_tool_v1_interface;
  extern const wl_interface zwp_tablet_v1_interface;
  extern const wl_interface zwp_tablet_manager_v2_interface;
  extern const wl_interface zwp_tablet_seat_v2_interface;
  extern const wl_interface zwp_tablet_tool_v2_interface;
  extern const wl_interface zwp_tablet_v2_interface;
  extern const wl_interface zwp_tablet_pad_ring_v2_interface;
  extern const wl_interface zwp_tablet_pad_strip_v2_interface;
  extern const wl_interface zwp_tablet_pad_group_v2_interface;
  extern const wl_interface zwp_tablet_pad_v2_interface;
  extern const wl_interface zwp_text_input_v1_interface;
  extern const wl_interface zwp_text_input_manager_v1_interface;
  extern const wl_interface zwp_text_input_v3_interface;
  extern const wl_interface zwp_text_input_manager_v3_interface;
  extern const wl_interface xdg_activation_v1_interface;
  extern const wl_interface xdg_activation_token_v1_interface;
  extern const wl_interface zxdg_decoration_manager_v1_interface;
  extern const wl_interface zxdg_toplevel_decoration_v1_interface;
  extern const wl_interface zxdg_exporter_v1_interface;
  extern const wl_interface zxdg_importer_v1_interface;
  extern const wl_interface zxdg_exported_v1_interface;
  extern const wl_interface zxdg_imported_v1_interface;
  extern const wl_interface zxdg_exporter_v2_interface;
  extern const wl_interface zxdg_importer_v2_interface;
  extern const wl_interface zxdg_exported_v2_interface;
  extern const wl_interface zxdg_imported_v2_interface;
  extern const wl_interface zxdg_output_manager_v1_interface;
  extern const wl_interface zxdg_output_v1_interface;
  extern const wl_interface zxdg_shell_v6_interface;
  extern const wl_interface zxdg_positioner_v6_interface;
  extern const wl_interface zxdg_surface_v6_interface;
  extern const wl_interface zxdg_toplevel_v6_interface;
  extern const wl_interface zxdg_popup_v6_interface;
  extern const wl_interface zwp_xwayland_keyboard_grab_manager_v1_interface;
  extern const wl_interface zwp_xwayland_keyboard_grab_v1_interface;
}

/** \brief displays a single surface per output

      Displays a single surface per output.

      This interface provides a mechanism for a single client to display
      simple full-screen surfaces.  While there technically may be multiple
      clients bound to this interface, only one of those clients should be
      shown at a time.

      To present a surface, the client uses either the present_surface or
      present_surface_for_mode requests.  Presenting a surface takes effect
      on the next wl_surface.commit.  See the individual requests for
      details about scaling and mode switches.

      The client can have at most one surface per output at any time.
      Requesting a surface to be presented on an output that already has a
      surface replaces the previously presented surface.  Presenting a null
      surface removes its content and effectively disables the output.
      Exactly what happens when an output is "disabled" is
      compositor-specific.  The same surface may be presented on multiple
      outputs simultaneously.

      Once a surface is presented on an output, it stays on that output
      until either the client removes it or the compositor destroys the
      output.  This way, the client can update the output's contents by
      simply attaching a new buffer.

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_fullscreen_shell_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> release;
    std::function<void(surface_t, zwp_fullscreen_shell_v1_present_method, output_t)> present_surface;
    std::function<void(surface_t, output_t, int32_t, zwp_fullscreen_shell_mode_feedback_v1_t)> present_surface_for_mode;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_fullscreen_shell_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_fullscreen_shell_v1_t>;
  friend class global_base_t;

public:
  zwp_fullscreen_shell_v1_t() = default;
  zwp_fullscreen_shell_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_fullscreen_shell_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_fullscreen_shell_v1*() const;

  /** \brief release the wl_fullscreen_shell interface

	Release the binding from the wl_fullscreen_shell interface.

	This destroys the server-side object and frees this binding.  If
	the client binds to wl_fullscreen_shell multiple times, it may wish
	to free some of those bindings.
      
  */
  std::function<void()> &on_release();

  /** \brief present surface for display
      \param surface 
      \param method 
      \param output 

	Present a surface on the given output.

	If the output is null, the compositor will present the surface on
	whatever display (or displays) it thinks best.  In particular, this
	may replace any or all surfaces currently presented so it should
	not be used in combination with placing surfaces on specific
	outputs.

	The method parameter is a hint to the compositor for how the surface
	is to be presented.  In particular, it tells the compositor how to
	handle a size mismatch between the presented surface and the
	output.  The compositor is free to ignore this parameter.

	The "zoom", "zoom_crop", and "stretch" methods imply a scaling
	operation on the surface.  This will override any kind of output
	scaling, so the buffer_scale property of the surface is effectively
	ignored.

	This request gives the surface the role of a fullscreen shell surface.
	If the surface already has another role, it raises a role protocol
	error.
      
  */
  std::function<void(surface_t, zwp_fullscreen_shell_v1_present_method, output_t)> &on_present_surface();

  /** \brief present surface for display at a particular mode
      \param surface 
      \param output 
      \param framerate 
      \param feedback 

	Presents a surface on the given output for a particular mode.

	If the current size of the output differs from that of the surface,
	the compositor will attempt to change the size of the output to
	match the surface.  The result of the mode-switch operation will be
	returned via the provided wl_fullscreen_shell_mode_feedback object.

	If the current output mode matches the one requested or if the
	compositor successfully switches the mode to match the surface,
	then the mode_successful event will be sent and the output will
	contain the contents of the given surface.  If the compositor
	cannot match the output size to the surface size, the mode_failed
	will be sent and the output will contain the contents of the
	previously presented surface (if any).  If another surface is
	presented on the given output before either of these has a chance
	to happen, the present_cancelled event will be sent.

	Due to race conditions and other issues unknown to the client, no
	mode-switch operation is guaranteed to succeed.  However, if the
	mode is one advertised by wl_output.mode or if the compositor
	advertises the ARBITRARY_MODES capability, then the client should
	expect that the mode-switch operation will usually succeed.

	If the size of the presented surface changes, the resulting output
	is undefined.  The compositor may attempt to change the output mode
	to compensate.  However, there is no guarantee that a suitable mode
	will be found and the client has no way to be notified of success
	or failure.

	The framerate parameter specifies the desired framerate for the
	output in mHz.  The compositor is free to ignore this parameter.  A
	value of 0 indicates that the client has no preference.

	If the value of wl_output.scale differs from wl_surface.buffer_scale,
	then the compositor may choose a mode that matches either the buffer
	size or the surface size.  In either case, the surface will fill the
	output.

	This request gives the surface the role of a fullscreen shell surface.
	If the surface already has another role, it raises a role protocol
	error.
      
  */
  std::function<void(surface_t, output_t, int32_t, zwp_fullscreen_shell_mode_feedback_v1_t)> &on_present_surface_for_mode();

  /** \brief advertises a capability of the compositor
      \param capability 

	Advertises a single capability of the compositor.

	When the wl_fullscreen_shell interface is bound, this event is emitted
	once for each capability advertised.  Valid capabilities are given by
	the wl_fullscreen_shell.capability enum.  If clients want to take
	advantage of any of these capabilities, they should use a
	wl_display.sync request immediately after binding to ensure that they
	receive all the capability events.
      
  */
  void capability(zwp_fullscreen_shell_v1_capability const& capability, bool post = true);

  /** \brief Minimum protocol version required for the \ref capability function
  */
  static constexpr std::uint32_t capability_since_version = 1;

  /** \brief Post error: present_method is not known
  */
  void post_invalid_method(std::string const& msg);

  /** \brief Post error: given wl_surface has another role
  */
  void post_role(std::string const& msg);

};

using global_zwp_fullscreen_shell_v1_t = global_t<zwp_fullscreen_shell_v1_t>;

/** \brief capabilities advertised by the compositor

	Various capabilities that can be advertised by the compositor.  They
	are advertised one-at-a-time when the wl_fullscreen_shell interface is
	bound.  See the wl_fullscreen_shell.capability event for more details.

	ARBITRARY_MODES:
	This is a hint to the client that indicates that the compositor is
	capable of setting practically any mode on its outputs.  If this
	capability is provided, wl_fullscreen_shell.present_surface_for_mode
	will almost never fail and clients should feel free to set whatever
	mode they like.  If the compositor does not advertise this, it may
	still support some modes that are not advertised through wl_global.mode
	but it is less likely.

	CURSOR_PLANE:
	This is a hint to the client that indicates that the compositor can
	handle a cursor surface from the client without actually compositing.
	This may be because of a hardware cursor plane or some other mechanism.
	If the compositor does not advertise this capability then setting
	wl_pointer.cursor may degrade performance or be ignored entirely.  If
	CURSOR_PLANE is not advertised, it is recommended that the client draw
	its own cursor and set wl_pointer.cursor(NULL).
      
  */
enum class zwp_fullscreen_shell_v1_capability : uint32_t
  {
  /** \brief compositor is capable of almost any output mode */
  arbitrary_modes = 1,
  /** \brief compositor has a separate cursor plane */
  cursor_plane = 2
};

/** \brief different method to set the surface fullscreen

	Hints to indicate to the compositor how to deal with a conflict
	between the dimensions of the surface and the dimensions of the
	output. The compositor is free to ignore this parameter.
      
  */
enum class zwp_fullscreen_shell_v1_present_method : uint32_t
  {
  /** \brief no preference, apply default policy */
  _default = 0,
  /** \brief center the surface on the output */
  center = 1,
  /** \brief scale the surface, preserving aspect ratio, to the largest size that will fit on the output */
  zoom = 2,
  /** \brief scale the surface, preserving aspect ratio, to fully fill the output cropping if needed */
  zoom_crop = 3,
  /** \brief scale the surface to the size of the output ignoring aspect ratio */
  stretch = 4
};

/** \brief wl_fullscreen_shell error values

	These errors can be emitted in response to wl_fullscreen_shell requests.
      
  */
enum class zwp_fullscreen_shell_v1_error : uint32_t
  {
  /** \brief present_method is not known */
  invalid_method = 0,
  /** \brief given wl_surface has another role */
  role = 1
};


/** \brief 

*/
class zwp_fullscreen_shell_mode_feedback_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_fullscreen_shell_mode_feedback_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_fullscreen_shell_mode_feedback_v1_t>;
  friend class global_base_t;

public:
  zwp_fullscreen_shell_mode_feedback_v1_t() = default;
  zwp_fullscreen_shell_mode_feedback_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_fullscreen_shell_mode_feedback_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_fullscreen_shell_mode_feedback_v1*() const;

  /** \brief mode switch succeeded

	This event indicates that the attempted mode switch operation was
	successful.  A surface of the size requested in the mode switch
	will fill the output without scaling.

	Upon receiving this event, the client should destroy the
	wl_fullscreen_shell_mode_feedback object.
      
  */
  void mode_successful(bool post = true);

  /** \brief Minimum protocol version required for the \ref mode_successful function
  */
  static constexpr std::uint32_t mode_successful_since_version = 1;

  /** \brief mode switch failed

	This event indicates that the attempted mode switch operation
	failed.  This may be because the requested output mode is not
	possible or it may mean that the compositor does not want to allow it.

	Upon receiving this event, the client should destroy the
	wl_fullscreen_shell_mode_feedback object.
      
  */
  void mode_failed(bool post = true);

  /** \brief Minimum protocol version required for the \ref mode_failed function
  */
  static constexpr std::uint32_t mode_failed_since_version = 1;

  /** \brief mode switch cancelled

	This event indicates that the attempted mode switch operation was
	cancelled.  Most likely this is because the client requested a
	second mode switch before the first one completed.

	Upon receiving this event, the client should destroy the
	wl_fullscreen_shell_mode_feedback object.
      
  */
  void present_cancelled(bool post = true);

  /** \brief Minimum protocol version required for the \ref present_cancelled function
  */
  static constexpr std::uint32_t present_cancelled_since_version = 1;

};

using global_zwp_fullscreen_shell_mode_feedback_v1_t = global_t<zwp_fullscreen_shell_mode_feedback_v1_t>;


/** \brief control behavior when display idles

      This interface permits inhibiting the idle behavior such as screen
      blanking, locking, and screensaving.  The client binds the idle manager
      globally, then creates idle-inhibitor objects for each surface.

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_idle_inhibit_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_idle_inhibitor_v1_t, surface_t)> create_inhibitor;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_idle_inhibit_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_idle_inhibit_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_idle_inhibit_manager_v1_t() = default;
  zwp_idle_inhibit_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_idle_inhibit_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_idle_inhibit_manager_v1*() const;

  /** \brief destroy the idle inhibitor object

	Destroy the inhibit manager.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create a new inhibitor object
      \param id 
      \param surface the surface that inhibits the idle behavior

	Create a new inhibitor object associated with the given surface.
      
  */
  std::function<void(zwp_idle_inhibitor_v1_t, surface_t)> &on_create_inhibitor();

};

using global_zwp_idle_inhibit_manager_v1_t = global_t<zwp_idle_inhibit_manager_v1_t>;


/** \brief context object for inhibiting idle behavior

      An idle inhibitor prevents the output that the associated surface is
      visible on from being set to a state where it is not visually usable due
      to lack of user interaction (e.g. blanked, dimmed, locked, set to power
      save, etc.)  Any screensaver processes are also blocked from displaying.

      If the surface is destroyed, unmapped, becomes occluded, loses
      visibility, or otherwise becomes not visually relevant for the user, the
      idle inhibitor will not be honored by the compositor; if the surface
      subsequently regains visibility the inhibitor takes effect once again.
      Likewise, the inhibitor isn't honored if the system was already idled at
      the time the inhibitor was established, although if the system later
      de-idles and re-idles the inhibitor will take effect.
    
*/
class zwp_idle_inhibitor_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_idle_inhibitor_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_idle_inhibitor_v1_t>;
  friend class global_base_t;

public:
  zwp_idle_inhibitor_v1_t() = default;
  zwp_idle_inhibitor_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_idle_inhibitor_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_idle_inhibitor_v1*() const;

  /** \brief destroy the idle inhibitor object

	Remove the inhibitor effect from the associated wl_surface.
      
  */
  std::function<void()> &on_destroy();

};

using global_zwp_idle_inhibitor_v1_t = global_t<zwp_idle_inhibitor_v1_t>;


/** \brief input method context

      Corresponds to a text input on the input method side. An input method context
      is created on text input activation on the input method side. It allows
      receiving information about the text input from the application via events.
      Input method contexts do not keep state after deactivation and should be
      destroyed after deactivation is handled.

      Text is generally UTF-8 encoded, indices and lengths are in bytes.

      Serials are used to synchronize the state between the text input and
      an input method. New serials are sent by the text input in the
      commit_state request and are used by the input method to indicate
      the known text input state in events like preedit_string, commit_string,
      and keysym. The text input can then ignore events from the input method
      which are based on an outdated state (for example after a reset).

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_input_method_context_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(uint32_t, std::string)> commit_string;
    std::function<void(uint32_t, std::string, std::string)> preedit_string;
    std::function<void(uint32_t, uint32_t, zwp_text_input_v1_preedit_style)> preedit_styling;
    std::function<void(int32_t)> preedit_cursor;
    std::function<void(int32_t, uint32_t)> delete_surrounding_text;
    std::function<void(int32_t, int32_t)> cursor_position;
    std::function<void(array_t)> modifiers_map;
    std::function<void(uint32_t, uint32_t, uint32_t, keyboard_key_state, uint32_t)> keysym;
    std::function<void(keyboard_t)> grab_keyboard;
    std::function<void(uint32_t, uint32_t, uint32_t, keyboard_key_state)> key;
    std::function<void(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)> modifiers;
    std::function<void(uint32_t, std::string)> language;
    std::function<void(uint32_t, uint32_t)> text_direction;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_input_method_context_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_input_method_context_v1_t>;
  friend class global_base_t;

public:
  zwp_input_method_context_v1_t() = default;
  zwp_input_method_context_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_input_method_context_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_input_method_context_v1*() const;

  /** \brief 

  */
  std::function<void()> &on_destroy();

  /** \brief commit string
      \param serial serial of the latest known text input state
      \param text 

	Send the commit string text for insertion to the application.

	The text to commit could be either just a single character after a key
	press or the result of some composing (pre-edit). It could be also an
	empty text when some text should be removed (see
	delete_surrounding_text) or when the input cursor should be moved (see
	cursor_position).

	Any previously set composing text will be removed.
      
  */
  std::function<void(uint32_t, std::string)> &on_commit_string();

  /** \brief pre-edit string
      \param serial serial of the latest known text input state
      \param text 
      \param commit 

	Send the pre-edit string text to the application text input.

	The commit text can be used to replace the pre-edit text on reset (for
	example on unfocus).

	Previously sent preedit_style and preedit_cursor requests are also
	processed by the text_input.
      
  */
  std::function<void(uint32_t, std::string, std::string)> &on_preedit_string();

  /** \brief pre-edit styling
      \param index 
      \param length 
      \param style 

	Set the styling information on composing text. The style is applied for
	length in bytes from index relative to the beginning of
	the composing text (as byte offset). Multiple styles can
	be applied to a composing text.

	This request should be sent before sending a preedit_string request.
      
  */
  std::function<void(uint32_t, uint32_t, zwp_text_input_v1_preedit_style)> &on_preedit_styling();

  /** \brief pre-edit cursor
      \param index 

	Set the cursor position inside the composing text (as byte offset)
	relative to the start of the composing text.

	When index is negative no cursor should be displayed.

	This request should be sent before sending a preedit_string request.
      
  */
  std::function<void(int32_t)> &on_preedit_cursor();

  /** \brief delete text
      \param index 
      \param length 

	Remove the surrounding text.

	This request will be handled on the text_input side directly following
	a commit_string request.
      
  */
  std::function<void(int32_t, uint32_t)> &on_delete_surrounding_text();

  /** \brief set cursor to a new position
      \param index 
      \param anchor 

	Set the cursor and anchor to a new position. Index is the new cursor
	position in bytes (when >= 0 this is relative to the end of the inserted text,
	otherwise it is relative to the beginning of the inserted text). Anchor is
	the new anchor position in bytes (when >= 0 this is relative to the end of the
	inserted text, otherwise it is relative to the beginning of the inserted
	text). When there should be no selected text, anchor should be the same
	as index.

	This request will be handled on the text_input side directly following
	a commit_string request.
      
  */
  std::function<void(int32_t, int32_t)> &on_cursor_position();

  /** \brief 
      \param map 

  */
  std::function<void(array_t)> &on_modifiers_map();

  /** \brief keysym
      \param serial serial of the latest known text input state
      \param time 
      \param sym 
      \param state 
      \param modifiers 

	Notify when a key event was sent. Key events should not be used for
	normal text input operations, which should be done with commit_string,
	delete_surrounding_text, etc. The key event follows the wl_keyboard key
	event convention. Sym is an XKB keysym, state is a wl_keyboard key_state.
      
  */
  std::function<void(uint32_t, uint32_t, uint32_t, keyboard_key_state, uint32_t)> &on_keysym();

  /** \brief grab hardware keyboard
      \param keyboard 

	Allow an input method to receive hardware keyboard input and process
	key events to generate text events (with pre-edit) over the wire. This
	allows input methods which compose multiple key events for inputting
	text like it is done for CJK languages.
      
  */
  std::function<void(keyboard_t)> &on_grab_keyboard();

  /** \brief forward key event
      \param serial serial from wl_keyboard::key
      \param time time from wl_keyboard::key
      \param key key from wl_keyboard::key
      \param state state from wl_keyboard::key

	Forward a wl_keyboard::key event to the client that was not processed
	by the input method itself. Should be used when filtering key events
	with grab_keyboard.  The arguments should be the ones from the
	wl_keyboard::key event.

	For generating custom key events use the keysym request instead.
      
  */
  std::function<void(uint32_t, uint32_t, uint32_t, keyboard_key_state)> &on_key();

  /** \brief forward modifiers event
      \param serial serial from wl_keyboard::modifiers
      \param mods_depressed mods_depressed from wl_keyboard::modifiers
      \param mods_latched mods_latched from wl_keyboard::modifiers
      \param mods_locked mods_locked from wl_keyboard::modifiers
      \param group group from wl_keyboard::modifiers

	Forward a wl_keyboard::modifiers event to the client that was not
	processed by the input method itself.  Should be used when filtering
	key events with grab_keyboard. The arguments should be the ones
	from the wl_keyboard::modifiers event.
      
  */
  std::function<void(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)> &on_modifiers();

  /** \brief 
      \param serial serial of the latest known text input state
      \param language 

  */
  std::function<void(uint32_t, std::string)> &on_language();

  /** \brief 
      \param serial serial of the latest known text input state
      \param direction 

  */
  std::function<void(uint32_t, uint32_t)> &on_text_direction();

  /** \brief surrounding text event
      \param text 
      \param cursor 
      \param anchor 

	The plain surrounding text around the input position. Cursor is the
	position in bytes within the surrounding text relative to the beginning
	of the text. Anchor is the position in bytes of the selection anchor
	within the surrounding text relative to the beginning of the text. If
	there is no selected text then anchor is the same as cursor.
      
  */
  void surrounding_text(std::string const& text, uint32_t cursor, uint32_t anchor, bool post = true);

  /** \brief Minimum protocol version required for the \ref surrounding_text function
  */
  static constexpr std::uint32_t surrounding_text_since_version = 1;

  /** \brief 

  */
  void reset(bool post = true);

  /** \brief Minimum protocol version required for the \ref reset function
  */
  static constexpr std::uint32_t reset_since_version = 1;

  /** \brief 
      \param hint 
      \param purpose 

  */
  void content_type(zwp_text_input_v1_content_hint const& hint, zwp_text_input_v1_content_purpose const& purpose, bool post = true);

  /** \brief Minimum protocol version required for the \ref content_type function
  */
  static constexpr std::uint32_t content_type_since_version = 1;

  /** \brief 
      \param button 
      \param index 

  */
  void invoke_action(uint32_t button, uint32_t index, bool post = true);

  /** \brief Minimum protocol version required for the \ref invoke_action function
  */
  static constexpr std::uint32_t invoke_action_since_version = 1;

  /** \brief 
      \param serial serial of text input state

  */
  void commit_state(uint32_t serial, bool post = true);

  /** \brief Minimum protocol version required for the \ref commit_state function
  */
  static constexpr std::uint32_t commit_state_since_version = 1;

  /** \brief 
      \param language 

  */
  void preferred_language(std::string const& language, bool post = true);

  /** \brief Minimum protocol version required for the \ref preferred_language function
  */
  static constexpr std::uint32_t preferred_language_since_version = 1;

};

using global_zwp_input_method_context_v1_t = global_t<zwp_input_method_context_v1_t>;


/** \brief input method

      An input method object is responsible for composing text in response to
      input from hardware or virtual keyboards. There is one input method
      object per seat. On activate there is a new input method context object
      created which allows the input method to communicate with the text input.
    
*/
class zwp_input_method_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_input_method_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_input_method_v1_t>;
  friend class global_base_t;

public:
  zwp_input_method_v1_t() = default;
  zwp_input_method_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_input_method_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_input_method_v1*() const;

  /** \brief activate event

	A text input was activated. Creates an input method context object
	which allows communication with the text input.
      
  */
  void activate(bool post = true);

  /** \brief Minimum protocol version required for the \ref activate function
  */
  static constexpr std::uint32_t activate_since_version = 1;

  /** \brief deactivate event
      \param context 

	The text input corresponding to the context argument was deactivated.
	The input method context should be destroyed after deactivation is
	handled.
      
  */
  void deactivate(zwp_input_method_context_v1_t const& context, bool post = true);

  /** \brief Minimum protocol version required for the \ref deactivate function
  */
  static constexpr std::uint32_t deactivate_since_version = 1;

};

using global_zwp_input_method_v1_t = global_t<zwp_input_method_v1_t>;


/** \brief interface for implementing keyboards

      Only one client can bind this interface at a time.
    
*/
class zwp_input_panel_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_input_panel_surface_v1_t, surface_t)> get_input_panel_surface;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_input_panel_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_input_panel_v1_t>;
  friend class global_base_t;

public:
  zwp_input_panel_v1_t() = default;
  zwp_input_panel_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_input_panel_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_input_panel_v1*() const;

  /** \brief 
      \param id 
      \param surface 

  */
  std::function<void(zwp_input_panel_surface_v1_t, surface_t)> &on_get_input_panel_surface();

};

using global_zwp_input_panel_v1_t = global_t<zwp_input_panel_v1_t>;


/** \brief 

*/
class zwp_input_panel_surface_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(output_t, zwp_input_panel_surface_v1_position)> set_toplevel;
    std::function<void()> set_overlay_panel;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_input_panel_surface_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_input_panel_surface_v1_t>;
  friend class global_base_t;

public:
  zwp_input_panel_surface_v1_t() = default;
  zwp_input_panel_surface_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_input_panel_surface_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_input_panel_surface_v1*() const;

  /** \brief set the surface type as a keyboard
      \param output 
      \param position 

	Set the input_panel_surface type to keyboard.

	A keyboard surface is only shown when a text input is active.
      
  */
  std::function<void(output_t, zwp_input_panel_surface_v1_position)> &on_set_toplevel();

  /** \brief set the surface type as an overlay panel

	Set the input_panel_surface to be an overlay panel.

	This is shown near the input cursor above the application window when
	a text input is active.
      
  */
  std::function<void()> &on_set_overlay_panel();

};

using global_zwp_input_panel_surface_v1_t = global_t<zwp_input_panel_surface_v1_t>;

/** \brief 

  */
enum class zwp_input_panel_surface_v1_position : uint32_t
  {
  center_bottom = 0
};


/** \brief context object for high-resolution input timestamps

      A global interface used for requesting high-resolution timestamps
      for input events.
    
*/
class zwp_input_timestamps_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_input_timestamps_v1_t, keyboard_t)> get_keyboard_timestamps;
    std::function<void(zwp_input_timestamps_v1_t, pointer_t)> get_pointer_timestamps;
    std::function<void(zwp_input_timestamps_v1_t, touch_t)> get_touch_timestamps;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_input_timestamps_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_input_timestamps_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_input_timestamps_manager_v1_t() = default;
  zwp_input_timestamps_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_input_timestamps_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_input_timestamps_manager_v1*() const;

  /** \brief destroy the input timestamps manager object

        Informs the server that the client will no longer be using this
        protocol object. Existing objects created by this object are not
        affected.
      
  */
  std::function<void()> &on_destroy();

  /** \brief subscribe to high-resolution keyboard timestamp events
      \param id 
      \param keyboard the wl_keyboard object for which to get timestamp events

        Creates a new input timestamps object that represents a subscription
        to high-resolution timestamp events for all wl_keyboard events that
        carry a timestamp.

        If the associated wl_keyboard object is invalidated, either through
        client action (e.g. release) or server-side changes, the input
        timestamps object becomes inert and the client should destroy it
        by calling zwp_input_timestamps_v1.destroy.
      
  */
  std::function<void(zwp_input_timestamps_v1_t, keyboard_t)> &on_get_keyboard_timestamps();

  /** \brief subscribe to high-resolution pointer timestamp events
      \param id 
      \param pointer the wl_pointer object for which to get timestamp events

        Creates a new input timestamps object that represents a subscription
        to high-resolution timestamp events for all wl_pointer events that
        carry a timestamp.

        If the associated wl_pointer object is invalidated, either through
        client action (e.g. release) or server-side changes, the input
        timestamps object becomes inert and the client should destroy it
        by calling zwp_input_timestamps_v1.destroy.
      
  */
  std::function<void(zwp_input_timestamps_v1_t, pointer_t)> &on_get_pointer_timestamps();

  /** \brief subscribe to high-resolution touch timestamp events
      \param id 
      \param touch the wl_touch object for which to get timestamp events

        Creates a new input timestamps object that represents a subscription
        to high-resolution timestamp events for all wl_touch events that
        carry a timestamp.

        If the associated wl_touch object becomes invalid, either through
        client action (e.g. release) or server-side changes, the input
        timestamps object becomes inert and the client should destroy it
        by calling zwp_input_timestamps_v1.destroy.
      
  */
  std::function<void(zwp_input_timestamps_v1_t, touch_t)> &on_get_touch_timestamps();

};

using global_zwp_input_timestamps_manager_v1_t = global_t<zwp_input_timestamps_manager_v1_t>;


/** \brief context object for input timestamps

      Provides high-resolution timestamp events for a set of subscribed input
      events. The set of subscribed input events is determined by the
      zwp_input_timestamps_manager_v1 request used to create this object.
    
*/
class zwp_input_timestamps_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_input_timestamps_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_input_timestamps_v1_t>;
  friend class global_base_t;

public:
  zwp_input_timestamps_v1_t() = default;
  zwp_input_timestamps_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_input_timestamps_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_input_timestamps_v1*() const;

  /** \brief destroy the input timestamps object

        Informs the server that the client will no longer be using this
        protocol object. After the server processes the request, no more
        timestamp events will be emitted.
      
  */
  std::function<void()> &on_destroy();

  /** \brief high-resolution timestamp event
      \param tv_sec_hi high 32 bits of the seconds part of the timestamp
      \param tv_sec_lo low 32 bits of the seconds part of the timestamp
      \param tv_nsec nanoseconds part of the timestamp

        The timestamp event is associated with the first subsequent input event
        carrying a timestamp which belongs to the set of input events this
        object is subscribed to.

        The timestamp provided by this event is a high-resolution version of
        the timestamp argument of the associated input event. The provided
        timestamp is in the same clock domain and is at least as accurate as
        the associated input event timestamp.

        The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples,
        each component being an unsigned 32-bit value. Whole seconds are in
        tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo,
        and the additional fractional part in tv_nsec as nanoseconds. Hence,
        for valid timestamps tv_nsec must be in [0, 999999999].
      
  */
  void timestamp(uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec, bool post = true);

  /** \brief Minimum protocol version required for the \ref timestamp function
  */
  static constexpr std::uint32_t timestamp_since_version = 1;

};

using global_zwp_input_timestamps_v1_t = global_t<zwp_input_timestamps_v1_t>;


/** \brief context object for keyboard grab_manager

      A global interface used for inhibiting the compositor keyboard shortcuts.
    
*/
class zwp_keyboard_shortcuts_inhibit_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_keyboard_shortcuts_inhibitor_v1_t, surface_t, seat_t)> inhibit_shortcuts;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_keyboard_shortcuts_inhibit_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_keyboard_shortcuts_inhibit_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_keyboard_shortcuts_inhibit_manager_v1_t() = default;
  zwp_keyboard_shortcuts_inhibit_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_keyboard_shortcuts_inhibit_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_keyboard_shortcuts_inhibit_manager_v1*() const;

  /** \brief destroy the keyboard shortcuts inhibitor object

	Destroy the keyboard shortcuts inhibitor manager.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create a new keyboard shortcuts inhibitor object
      \param id 
      \param surface the surface that inhibits the keyboard shortcuts behavior
      \param seat the wl_seat for which keyboard shortcuts should be disabled

	Create a new keyboard shortcuts inhibitor object associated with
	the given surface for the given seat.

	If shortcuts are already inhibited for the specified seat and surface,
	a protocol error "already_inhibited" is raised by the compositor.
      
  */
  std::function<void(zwp_keyboard_shortcuts_inhibitor_v1_t, surface_t, seat_t)> &on_inhibit_shortcuts();

  /** \brief Post error: the shortcuts are already inhibited for this surface
  */
  void post_already_inhibited(std::string const& msg);

};

using global_zwp_keyboard_shortcuts_inhibit_manager_v1_t = global_t<zwp_keyboard_shortcuts_inhibit_manager_v1_t>;

/** \brief 

  */
enum class zwp_keyboard_shortcuts_inhibit_manager_v1_error : uint32_t
  {
  /** \brief the shortcuts are already inhibited for this surface */
  already_inhibited = 0
};


/** \brief context object for keyboard shortcuts inhibitor

      A keyboard shortcuts inhibitor instructs the compositor to ignore
      its own keyboard shortcuts when the associated surface has keyboard
      focus. As a result, when the surface has keyboard focus on the given
      seat, it will receive all key events originating from the specified
      seat, even those which would normally be caught by the compositor for
      its own shortcuts.

      The Wayland compositor is however under no obligation to disable
      all of its shortcuts, and may keep some special key combo for its own
      use, including but not limited to one allowing the user to forcibly
      restore normal keyboard events routing in the case of an unwilling
      client. The compositor may also use the same key combo to reactivate
      an existing shortcut inhibitor that was previously deactivated on
      user request.

      When the compositor restores its own keyboard shortcuts, an
      "inactive" event is emitted to notify the client that the keyboard
      shortcuts inhibitor is not effectively active for the surface and
      seat any more, and the client should not expect to receive all
      keyboard events.

      When the keyboard shortcuts inhibitor is inactive, the client has
      no way to forcibly reactivate the keyboard shortcuts inhibitor.

      The user can chose to re-enable a previously deactivated keyboard
      shortcuts inhibitor using any mechanism the compositor may offer,
      in which case the compositor will send an "active" event to notify
      the client.

      If the surface is destroyed, unmapped, or loses the seat's keyboard
      focus, the keyboard shortcuts inhibitor becomes irrelevant and the
      compositor will restore its own keyboard shortcuts but no "inactive"
      event is emitted in this case.
    
*/
class zwp_keyboard_shortcuts_inhibitor_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_keyboard_shortcuts_inhibitor_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_keyboard_shortcuts_inhibitor_v1_t>;
  friend class global_base_t;

public:
  zwp_keyboard_shortcuts_inhibitor_v1_t() = default;
  zwp_keyboard_shortcuts_inhibitor_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_keyboard_shortcuts_inhibitor_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_keyboard_shortcuts_inhibitor_v1*() const;

  /** \brief destroy the keyboard shortcuts inhibitor object

	Remove the keyboard shortcuts inhibitor from the associated wl_surface.
      
  */
  std::function<void()> &on_destroy();

  /** \brief shortcuts are inhibited

	This event indicates that the shortcut inhibitor is active.

	The compositor sends this event every time compositor shortcuts
	are inhibited on behalf of the surface. When active, the client
	may receive input events normally reserved by the compositor
	(see zwp_keyboard_shortcuts_inhibitor_v1).

	This occurs typically when the initial request "inhibit_shortcuts"
	first becomes active or when the user instructs the compositor to
	re-enable and existing shortcuts inhibitor using any mechanism
	offered by the compositor.
      
  */
  void active(bool post = true);

  /** \brief Minimum protocol version required for the \ref active function
  */
  static constexpr std::uint32_t active_since_version = 1;

  /** \brief shortcuts are restored

	This event indicates that the shortcuts inhibitor is inactive,
	normal shortcuts processing is restored by the compositor.
       
  */
  void inactive(bool post = true);

  /** \brief Minimum protocol version required for the \ref inactive function
  */
  static constexpr std::uint32_t inactive_since_version = 1;

};

using global_zwp_keyboard_shortcuts_inhibitor_v1_t = global_t<zwp_keyboard_shortcuts_inhibitor_v1_t>;


/** \brief factory for creating dmabuf-based wl_buffers

      Following the interfaces from:
      https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt
      https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
      and the Linux DRM sub-system's AddFb2 ioctl.

      This interface offers ways to create generic dmabuf-based wl_buffers.

      Clients can use the get_surface_feedback request to get dmabuf feedback
      for a particular surface. If the client wants to retrieve feedback not
      tied to a surface, they can use the get_default_feedback request.

      The following are required from clients:

      - Clients must ensure that either all data in the dma-buf is
        coherent for all subsequent read access or that coherency is
        correctly handled by the underlying kernel-side dma-buf
        implementation.

      - Don't make any more attachments after sending the buffer to the
        compositor. Making more attachments later increases the risk of
        the compositor not being able to use (re-import) an existing
        dmabuf-based wl_buffer.

      The underlying graphics stack must ensure the following:

      - The dmabuf file descriptors relayed to the server will stay valid
        for the whole lifetime of the wl_buffer. This means the server may
        at any time use those fds to import the dmabuf into any kernel
        sub-system that might accept it.

      However, when the underlying graphics stack fails to deliver the
      promise, because of e.g. a device hot-unplug which raises internal
      errors, after the wl_buffer has been successfully created the
      compositor must not raise protocol errors to the client when dmabuf
      import later fails.

      To create a wl_buffer from one or more dmabufs, a client creates a
      zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params
      request. All planes required by the intended format are added with
      the 'add' request. Finally, a 'create' or 'create_immed' request is
      issued, which has the following outcome depending on the import success.

      The 'create' request,
      - on success, triggers a 'created' event which provides the final
        wl_buffer to the client.
      - on failure, triggers a 'failed' event to convey that the server
        cannot use the dmabufs received from the client.

      For the 'create_immed' request,
      - on success, the server immediately imports the added dmabufs to
        create a wl_buffer. No event is sent from the server in this case.
      - on failure, the server can choose to either:
        - terminate the client by raising a fatal error.
        - mark the wl_buffer as failed, and send a 'failed' event to the
          client. If the client uses a failed wl_buffer as an argument to any
          request, the behaviour is compositor implementation-defined.

      For all DRM formats and unless specified in another protocol extension,
      pre-multiplied alpha is used for pixel values.

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_linux_dmabuf_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_linux_buffer_params_v1_t)> create_params;
    std::function<void(zwp_linux_dmabuf_feedback_v1_t)> get_default_feedback;
    std::function<void(zwp_linux_dmabuf_feedback_v1_t, surface_t)> get_surface_feedback;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_linux_dmabuf_v1_interface;
  static constexpr const unsigned int max_version = 4;

  friend class global_t<zwp_linux_dmabuf_v1_t>;
  friend class global_base_t;

public:
  zwp_linux_dmabuf_v1_t() = default;
  zwp_linux_dmabuf_v1_t(const client_t& client, uint32_t id, int version = 4);
  zwp_linux_dmabuf_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_linux_dmabuf_v1*() const;

  /** \brief unbind the factory

        Objects created through this interface, especially wl_buffers, will
        remain valid.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create a temporary object for buffer parameters
      \param params_id the new temporary

        This temporary object is used to collect multiple dmabuf handles into
        a single batch to create a wl_buffer. It can only be used once and
        should be destroyed after a 'created' or 'failed' event has been
        received.
      
  */
  std::function<void(zwp_linux_buffer_params_v1_t)> &on_create_params();

  /** \brief get default feedback
      \param id 

        This request creates a new wp_linux_dmabuf_feedback object not bound
        to a particular surface. This object will deliver feedback about dmabuf
        parameters to use if the client doesn't support per-surface feedback
        (see get_surface_feedback).
      
  */
  std::function<void(zwp_linux_dmabuf_feedback_v1_t)> &on_get_default_feedback();

  /** \brief get feedback for a surface
      \param id 
      \param surface 

        This request creates a new wp_linux_dmabuf_feedback object for the
        specified wl_surface. This object will deliver feedback about dmabuf
        parameters to use for buffers attached to this surface.

        If the surface is destroyed before the wp_linux_dmabuf_feedback object,
        the feedback object becomes inert.
      
  */
  std::function<void(zwp_linux_dmabuf_feedback_v1_t, surface_t)> &on_get_surface_feedback();

  /** \brief supported buffer format
      \param format DRM_FORMAT code

        This event advertises one buffer format that the server supports.
        All the supported formats are advertised once when the client
        binds to this interface. A roundtrip after binding guarantees
        that the client has received all supported formats.

        For the definition of the format codes, see the
        zwp_linux_buffer_params_v1::create request.

        Starting version 4, the format event is deprecated and must not be
        sent by compositors. Instead, use get_default_feedback or
        get_surface_feedback.
      
  */
  void format(uint32_t format, bool post = true);

  /** \brief Minimum protocol version required for the \ref format function
  */
  static constexpr std::uint32_t format_since_version = 1;

  /** \brief supported buffer format modifier
      \param format DRM_FORMAT code
      \param modifier_hi high 32 bits of layout modifier
      \param modifier_lo low 32 bits of layout modifier

        This event advertises the formats that the server supports, along with
        the modifiers supported for each format. All the supported modifiers
        for all the supported formats are advertised once when the client
        binds to this interface. A roundtrip after binding guarantees that
        the client has received all supported format-modifier pairs.

        For legacy support, DRM_FORMAT_MOD_INVALID (that is, modifier_hi ==
        0x00ffffff and modifier_lo == 0xffffffff) is allowed in this event.
        It indicates that the server can support the format with an implicit
        modifier. When a plane has DRM_FORMAT_MOD_INVALID as its modifier, it
        is as if no explicit modifier is specified. The effective modifier
        will be derived from the dmabuf.

        A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for
        a given format supports both explicit modifiers and implicit modifiers.

        For the definition of the format and modifier codes, see the
        zwp_linux_buffer_params_v1::create and zwp_linux_buffer_params_v1::add
        requests.

        Starting version 4, the modifier event is deprecated and must not be
        sent by compositors. Instead, use get_default_feedback or
        get_surface_feedback.
      
  */
  void modifier(uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo, bool post = true);

  /** \brief Minimum protocol version required for the \ref modifier function
  */
  static constexpr std::uint32_t modifier_since_version = 3;

  /** \brief Check whether the \ref modifier function is available with
      the currently bound version of the protocol
  */
  bool can_modifier() const;

};

using global_zwp_linux_dmabuf_v1_t = global_t<zwp_linux_dmabuf_v1_t>;


/** \brief parameters for creating a dmabuf-based wl_buffer

      This temporary object is a collection of dmabufs and other
      parameters that together form a single logical buffer. The temporary
      object may eventually create one wl_buffer unless cancelled by
      destroying it before requesting 'create'.

      Single-planar formats only require one dmabuf, however
      multi-planar formats may require more than one dmabuf. For all
      formats, an 'add' request must be called once per plane (even if the
      underlying dmabuf fd is identical).

      You must use consecutive plane indices ('plane_idx' argument for 'add')
      from zero to the number of planes used by the drm_fourcc format code.
      All planes required by the format must be given exactly once, but can
      be given in any order. Each plane index can be set only once.
    
*/
class zwp_linux_buffer_params_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(int, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)> add;
    std::function<void(int32_t, int32_t, uint32_t, zwp_linux_buffer_params_v1_flags)> create;
    std::function<void(buffer_t, int32_t, int32_t, uint32_t, zwp_linux_buffer_params_v1_flags)> create_immed;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_linux_buffer_params_v1_interface;
  static constexpr const unsigned int max_version = 4;

  friend class global_t<zwp_linux_buffer_params_v1_t>;
  friend class global_base_t;

public:
  zwp_linux_buffer_params_v1_t() = default;
  zwp_linux_buffer_params_v1_t(const client_t& client, uint32_t id, int version = 4);
  zwp_linux_buffer_params_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_linux_buffer_params_v1*() const;

  /** \brief delete this object, used or not

        Cleans up the temporary data sent to the server for dmabuf-based
        wl_buffer creation.
      
  */
  std::function<void()> &on_destroy();

  /** \brief add a dmabuf to the temporary set
      \param fd dmabuf fd
      \param plane_idx plane index
      \param offset offset in bytes
      \param stride stride in bytes
      \param modifier_hi high 32 bits of layout modifier
      \param modifier_lo low 32 bits of layout modifier

        This request adds one dmabuf to the set in this
        zwp_linux_buffer_params_v1.

        The 64-bit unsigned value combined from modifier_hi and modifier_lo
        is the dmabuf layout modifier. DRM AddFB2 ioctl calls this the
        fb modifier, which is defined in drm_mode.h of Linux UAPI.
        This is an opaque token. Drivers use this token to express tiling,
        compression, etc. driver-specific modifications to the base format
        defined by the DRM fourcc code.

        Starting from version 4, the invalid_format protocol error is sent if
        the format + modifier pair was not advertised as supported.

        This request raises the PLANE_IDX error if plane_idx is too large.
        The error PLANE_SET is raised if attempting to set a plane that
        was already set.
      
  */
  std::function<void(int, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)> &on_add();

  /** \brief create a wl_buffer from the given dmabufs
      \param width base plane width in pixels
      \param height base plane height in pixels
      \param format DRM_FORMAT code
      \param flags see enum flags

        This asks for creation of a wl_buffer from the added dmabuf
        buffers. The wl_buffer is not created immediately but returned via
        the 'created' event if the dmabuf sharing succeeds. The sharing
        may fail at runtime for reasons a client cannot predict, in
        which case the 'failed' event is triggered.

        The 'format' argument is a DRM_FORMAT code, as defined by the
        libdrm's drm_fourcc.h. The Linux kernel's DRM sub-system is the
        authoritative source on how the format codes should work.

        The 'flags' is a bitfield of the flags defined in enum "flags".
        'y_invert' means the that the image needs to be y-flipped.

        Flag 'interlaced' means that the frame in the buffer is not
        progressive as usual, but interlaced. An interlaced buffer as
        supported here must always contain both top and bottom fields.
        The top field always begins on the first pixel row. The temporal
        ordering between the two fields is top field first, unless
        'bottom_first' is specified. It is undefined whether 'bottom_first'
        is ignored if 'interlaced' is not set.

        This protocol does not convey any information about field rate,
        duration, or timing, other than the relative ordering between the
        two fields in one buffer. A compositor may have to estimate the
        intended field rate from the incoming buffer rate. It is undefined
        whether the time of receiving wl_surface.commit with a new buffer
        attached, applying the wl_surface state, wl_surface.frame callback
        trigger, presentation, or any other point in the compositor cycle
        is used to measure the frame or field times. There is no support
        for detecting missed or late frames/fields/buffers either, and
        there is no support whatsoever for cooperating with interlaced
        compositor output.

        The composited image quality resulting from the use of interlaced
        buffers is explicitly undefined. A compositor may use elaborate
        hardware features or software to deinterlace and create progressive
        output frames from a sequence of interlaced input buffers, or it
        may produce substandard image quality. However, compositors that
        cannot guarantee reasonable image quality in all cases are recommended
        to just reject all interlaced buffers.

        Any argument errors, including non-positive width or height,
        mismatch between the number of planes and the format, bad
        format, bad offset or stride, may be indicated by fatal protocol
        errors: INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS,
        OUT_OF_BOUNDS.

        Dmabuf import errors in the server that are not obvious client
        bugs are returned via the 'failed' event as non-fatal. This
        allows attempting dmabuf sharing and falling back in the client
        if it fails.

        This request can be sent only once in the object's lifetime, after
        which the only legal request is destroy. This object should be
        destroyed after issuing a 'create' request. Attempting to use this
        object after issuing 'create' raises ALREADY_USED protocol error.

        It is not mandatory to issue 'create'. If a client wants to
        cancel the buffer creation, it can just destroy this object.
      
  */
  std::function<void(int32_t, int32_t, uint32_t, zwp_linux_buffer_params_v1_flags)> &on_create();

  /** \brief immediately create a wl_buffer from the given                      dmabufs
      \param buffer_id id for the newly created wl_buffer
      \param width base plane width in pixels
      \param height base plane height in pixels
      \param format DRM_FORMAT code
      \param flags see enum flags

        This asks for immediate creation of a wl_buffer by importing the
        added dmabufs.

        In case of import success, no event is sent from the server, and the
        wl_buffer is ready to be used by the client.

        Upon import failure, either of the following may happen, as seen fit
        by the implementation:
        - the client is terminated with one of the following fatal protocol
          errors:
          - INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS,
            in case of argument errors such as mismatch between the number
            of planes and the format, bad format, non-positive width or
            height, or bad offset or stride.
          - INVALID_WL_BUFFER, in case the cause for failure is unknown or
            plaform specific.
        - the server creates an invalid wl_buffer, marks it as failed and
          sends a 'failed' event to the client. The result of using this
          invalid wl_buffer as an argument in any request by the client is
          defined by the compositor implementation.

        This takes the same arguments as a 'create' request, and obeys the
        same restrictions.
      
  */
  std::function<void(buffer_t, int32_t, int32_t, uint32_t, zwp_linux_buffer_params_v1_flags)> &on_create_immed();

  /** \brief buffer creation succeeded
      \return the newly created wl_buffer

        This event indicates that the attempted buffer creation was
        successful. It provides the new wl_buffer referencing the dmabuf(s).

        Upon receiving this event, the client should destroy the
        zlinux_dmabuf_params object.
      
  */
  void created(bool post = true);

  /** \brief Minimum protocol version required for the \ref created function
  */
  static constexpr std::uint32_t created_since_version = 1;

  /** \brief buffer creation failed

        This event indicates that the attempted buffer creation has
        failed. It usually means that one of the dmabuf constraints
        has not been fulfilled.

        Upon receiving this event, the client should destroy the
        zlinux_buffer_params object.
      
  */
  void failed(bool post = true);

  /** \brief Minimum protocol version required for the \ref failed function
  */
  static constexpr std::uint32_t failed_since_version = 1;

  /** \brief Post error: the dmabuf_batch object has already been used to create a wl_buffer
  */
  void post_already_used(std::string const& msg);

  /** \brief Post error: plane index out of bounds
  */
  void post_plane_idx(std::string const& msg);

  /** \brief Post error: the plane index was already set
  */
  void post_plane_set(std::string const& msg);

  /** \brief Post error: missing or too many planes to create a buffer
  */
  void post_incomplete(std::string const& msg);

  /** \brief Post error: format not supported
  */
  void post_invalid_format(std::string const& msg);

  /** \brief Post error: invalid width or height
  */
  void post_invalid_dimensions(std::string const& msg);

  /** \brief Post error: offset + stride * height goes out of dmabuf bounds
  */
  void post_out_of_bounds(std::string const& msg);

  /** \brief Post error: invalid wl_buffer resulted from importing dmabufs via                the create_immed request on given buffer_params
  */
  void post_invalid_wl_buffer(std::string const& msg);

};

using global_zwp_linux_buffer_params_v1_t = global_t<zwp_linux_buffer_params_v1_t>;

/** \brief 

  */
enum class zwp_linux_buffer_params_v1_error : uint32_t
  {
  /** \brief the dmabuf_batch object has already been used to create a wl_buffer */
  already_used = 0,
  /** \brief plane index out of bounds */
  plane_idx = 1,
  /** \brief the plane index was already set */
  plane_set = 2,
  /** \brief missing or too many planes to create a buffer */
  incomplete = 3,
  /** \brief format not supported */
  invalid_format = 4,
  /** \brief invalid width or height */
  invalid_dimensions = 5,
  /** \brief offset + stride * height goes out of dmabuf bounds */
  out_of_bounds = 6,
  /** \brief invalid wl_buffer resulted from importing dmabufs via                the create_immed request on given buffer_params */
  invalid_wl_buffer = 7
};

/** \brief 

  */
struct zwp_linux_buffer_params_v1_flags : public wayland::detail::bitfield<3, 6>
{
  zwp_linux_buffer_params_v1_flags(const wayland::detail::bitfield<3, 6> &b)
    : wayland::detail::bitfield<3, 6>(b) {}
  zwp_linux_buffer_params_v1_flags(const uint32_t value)
    : wayland::detail::bitfield<3, 6>(value) {}
  /** \brief contents are y-inverted */
  static const wayland::detail::bitfield<3, 6> y_invert;
  /** \brief content is interlaced */
  static const wayland::detail::bitfield<3, 6> interlaced;
  /** \brief bottom field first */
  static const wayland::detail::bitfield<3, 6> bottom_first;
};


/** \brief dmabuf feedback

      This object advertises dmabuf parameters feedback. This includes the
      preferred devices and the supported formats/modifiers.

      The parameters are sent once when this object is created and whenever they
      change. The done event is always sent once after all parameters have been
      sent. When a single parameter changes, all parameters are re-sent by the
      compositor.

      Compositors can re-send the parameters when the current client buffer
      allocations are sub-optimal. Compositors should not re-send the
      parameters if re-allocating the buffers would not result in a more optimal
      configuration. In particular, compositors should avoid sending the exact
      same parameters multiple times in a row.

      The tranche_target_device and tranche_modifier events are grouped by
      tranches of preference. For each tranche, a tranche_target_device, one
      tranche_flags and one or more tranche_modifier events are sent, followed
      by a tranche_done event finishing the list. The tranches are sent in
      descending order of preference. All formats and modifiers in the same
      tranche have the same preference.

      To send parameters, the compositor sends one main_device event, tranches
      (each consisting of one tranche_target_device event, one tranche_flags
      event, tranche_modifier events and then a tranche_done event), then one
      done event.
    
*/
class zwp_linux_dmabuf_feedback_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_linux_dmabuf_feedback_v1_interface;
  static constexpr const unsigned int max_version = 4;

  friend class global_t<zwp_linux_dmabuf_feedback_v1_t>;
  friend class global_base_t;

public:
  zwp_linux_dmabuf_feedback_v1_t() = default;
  zwp_linux_dmabuf_feedback_v1_t(const client_t& client, uint32_t id, int version = 4);
  zwp_linux_dmabuf_feedback_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_linux_dmabuf_feedback_v1*() const;

  /** \brief destroy the feedback object

        Using this request a client can tell the server that it is not going to
        use the wp_linux_dmabuf_feedback object anymore.
      
  */
  std::function<void()> &on_destroy();

  /** \brief all feedback has been sent

        This event is sent after all parameters of a wp_linux_dmabuf_feedback
        object have been sent.

        This allows changes to the wp_linux_dmabuf_feedback parameters to be
        seen as atomic, even if they happen via multiple events.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief format and modifier table
      \param fd table file descriptor
      \param size table size, in bytes

        This event provides a file descriptor which can be memory-mapped to
        access the format and modifier table.

        The table contains a tightly packed array of consecutive format +
        modifier pairs. Each pair is 16 bytes wide. It contains a format as a
        32-bit unsigned integer, followed by 4 bytes of unused padding, and a
        modifier as a 64-bit unsigned integer. The native endianness is used.

        The client must map the file descriptor in read-only private mode.

        Compositors are not allowed to mutate the table file contents once this
        event has been sent. Instead, compositors must create a new, separate
        table file and re-send feedback parameters. Compositors are allowed to
        store duplicate format + modifier pairs in the table.
      
  */
  void format_table(int fd, uint32_t size, bool post = true);

  /** \brief Minimum protocol version required for the \ref format_table function
  */
  static constexpr std::uint32_t format_table_since_version = 1;

  /** \brief preferred main device
      \param device device dev_t value

        This event advertises the main device that the server prefers to use
        when direct scan-out to the target device isn't possible. The
        advertised main device may be different for each
        wp_linux_dmabuf_feedback object, and may change over time.

        There is exactly one main device. The compositor must send at least
        one preference tranche with tranche_target_device equal to main_device.

        Clients need to create buffers that the main device can import and
        read from, otherwise creating the dmabuf wl_buffer will fail (see the
        wp_linux_buffer_params.create and create_immed requests for details).
        The main device will also likely be kept active by the compositor,
        so clients can use it instead of waking up another device for power
        savings.

        In general the device is a DRM node. The DRM node type (primary vs.
        render) is unspecified. Clients must not rely on the compositor sending
        a particular node type. Clients cannot check two devices for equality
        by comparing the dev_t value.

        If explicit modifiers are not supported and the client performs buffer
        allocations on a different device than the main device, then the client
        must force the buffer to have a linear layout.
      
  */
  void main_device(array_t const& device, bool post = true);

  /** \brief Minimum protocol version required for the \ref main_device function
  */
  static constexpr std::uint32_t main_device_since_version = 1;

  /** \brief a preference tranche has been sent

        This event splits tranche_target_device and tranche_modifier events in
        preference tranches. It is sent after a set of tranche_target_device
        and tranche_modifier events; it represents the end of a tranche. The
        next tranche will have a lower preference.
      
  */
  void tranche_done(bool post = true);

  /** \brief Minimum protocol version required for the \ref tranche_done function
  */
  static constexpr std::uint32_t tranche_done_since_version = 1;

  /** \brief target device
      \param device device dev_t value

        This event advertises the target device that the server prefers to use
        for a buffer created given this tranche. The advertised target device
        may be different for each preference tranche, and may change over time.

        There is exactly one target device per tranche.

        The target device may be a scan-out device, for example if the
        compositor prefers to directly scan-out a buffer created given this
        tranche. The target device may be a rendering device, for example if
        the compositor prefers to texture from said buffer.

        The client can use this hint to allocate the buffer in a way that makes
        it accessible from the target device, ideally directly. The buffer must
        still be accessible from the main device, either through direct import
        or through a potentially more expensive fallback path. If the buffer
        can't be directly imported from the main device then clients must be
        prepared for the compositor changing the tranche priority or making
        wl_buffer creation fail (see the wp_linux_buffer_params.create and
        create_immed requests for details).

        If the device is a DRM node, the DRM node type (primary vs. render) is
        unspecified. Clients must not rely on the compositor sending a
        particular node type. Clients cannot check two devices for equality by
        comparing the dev_t value.

        This event is tied to a preference tranche, see the tranche_done event.
      
  */
  void tranche_target_device(array_t const& device, bool post = true);

  /** \brief Minimum protocol version required for the \ref tranche_target_device function
  */
  static constexpr std::uint32_t tranche_target_device_since_version = 1;

  /** \brief supported buffer format modifier
      \param indices array of 16-bit indexes

        This event advertises the format + modifier combinations that the
        compositor supports.

        It carries an array of indices, each referring to a format + modifier
        pair in the last received format table (see the format_table event).
        Each index is a 16-bit unsigned integer in native endianness.

        For legacy support, DRM_FORMAT_MOD_INVALID is an allowed modifier.
        It indicates that the server can support the format with an implicit
        modifier. When a buffer has DRM_FORMAT_MOD_INVALID as its modifier, it
        is as if no explicit modifier is specified. The effective modifier
        will be derived from the dmabuf.

        A compositor that sends valid modifiers and DRM_FORMAT_MOD_INVALID for
        a given format supports both explicit modifiers and implicit modifiers.

        Compositors must not send duplicate format + modifier pairs within the
        same tranche or across two different tranches with the same target
        device and flags.

        This event is tied to a preference tranche, see the tranche_done event.

        For the definition of the format and modifier codes, see the
        wp_linux_buffer_params.create request.
      
  */
  void tranche_formats(array_t const& indices, bool post = true);

  /** \brief Minimum protocol version required for the \ref tranche_formats function
  */
  static constexpr std::uint32_t tranche_formats_since_version = 1;

  /** \brief tranche flags
      \param flags tranche flags

        This event sets tranche-specific flags.

        The scanout flag is a hint that direct scan-out may be attempted by the
        compositor on the target device if the client appropriately allocates a
        buffer. How to allocate a buffer that can be scanned out on the target
        device is implementation-defined.

        This event is tied to a preference tranche, see the tranche_done event.
      
  */
  void tranche_flags(zwp_linux_dmabuf_feedback_v1_tranche_flags const& flags, bool post = true);

  /** \brief Minimum protocol version required for the \ref tranche_flags function
  */
  static constexpr std::uint32_t tranche_flags_since_version = 1;

};

using global_zwp_linux_dmabuf_feedback_v1_t = global_t<zwp_linux_dmabuf_feedback_v1_t>;

/** \brief 

  */
struct zwp_linux_dmabuf_feedback_v1_tranche_flags : public wayland::detail::bitfield<1, 7>
{
  zwp_linux_dmabuf_feedback_v1_tranche_flags(const wayland::detail::bitfield<1, 7> &b)
    : wayland::detail::bitfield<1, 7>(b) {}
  zwp_linux_dmabuf_feedback_v1_tranche_flags(const uint32_t value)
    : wayland::detail::bitfield<1, 7>(value) {}
  /** \brief direct scan-out tranche */
  static const wayland::detail::bitfield<1, 7> scanout;
};


/** \brief protocol for providing explicit synchronization

      This global is a factory interface, allowing clients to request
      explicit synchronization for buffers on a per-surface basis.

      See zwp_linux_surface_synchronization_v1 for more information.

      This interface is derived from Chromium's
      zcr_linux_explicit_synchronization_v1.

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_linux_explicit_synchronization_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_linux_surface_synchronization_v1_t, surface_t)> get_synchronization;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_linux_explicit_synchronization_v1_interface;
  static constexpr const unsigned int max_version = 2;

  friend class global_t<zwp_linux_explicit_synchronization_v1_t>;
  friend class global_base_t;

public:
  zwp_linux_explicit_synchronization_v1_t() = default;
  zwp_linux_explicit_synchronization_v1_t(const client_t& client, uint32_t id, int version = 2);
  zwp_linux_explicit_synchronization_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_linux_explicit_synchronization_v1*() const;

  /** \brief destroy explicit synchronization factory object

        Destroy this explicit synchronization factory object. Other objects,
        including zwp_linux_surface_synchronization_v1 objects created by this
        factory, shall not be affected by this request.
      
  */
  std::function<void()> &on_destroy();

  /** \brief extend surface interface for explicit synchronization
      \param id the new synchronization interface id
      \param surface the surface

        Instantiate an interface extension for the given wl_surface to provide
        explicit synchronization.

        If the given wl_surface already has an explicit synchronization object
        associated, the synchronization_exists protocol error is raised.

        Graphics APIs, like EGL or Vulkan, that manage the buffer queue and
        commits of a wl_surface themselves, are likely to be using this
        extension internally. If a client is using such an API for a
        wl_surface, it should not directly use this extension on that surface,
        to avoid raising a synchronization_exists protocol error.
      
  */
  std::function<void(zwp_linux_surface_synchronization_v1_t, surface_t)> &on_get_synchronization();

  /** \brief Post error: the surface already has a synchronization object associated
  */
  void post_synchronization_exists(std::string const& msg);

};

using global_zwp_linux_explicit_synchronization_v1_t = global_t<zwp_linux_explicit_synchronization_v1_t>;

/** \brief 

  */
enum class zwp_linux_explicit_synchronization_v1_error : uint32_t
  {
  /** \brief the surface already has a synchronization object associated */
  synchronization_exists = 0
};


/** \brief per-surface explicit synchronization support

      This object implements per-surface explicit synchronization.

      Synchronization refers to co-ordination of pipelined operations performed
      on buffers. Most GPU clients will schedule an asynchronous operation to
      render to the buffer, then immediately send the buffer to the compositor
      to be attached to a surface.

      In implicit synchronization, ensuring that the rendering operation is
      complete before the compositor displays the buffer is an implementation
      detail handled by either the kernel or userspace graphics driver.

      By contrast, in explicit synchronization, dma_fence objects mark when the
      asynchronous operations are complete. When submitting a buffer, the
      client provides an acquire fence which will be waited on before the
      compositor accesses the buffer. The Wayland server, through a
      zwp_linux_buffer_release_v1 object, will inform the client with an event
      which may be accompanied by a release fence, when the compositor will no
      longer access the buffer contents due to the specific commit that
      requested the release event.

      Each surface can be associated with only one object of this interface at
      any time.

      In version 1 of this interface, explicit synchronization is only
      guaranteed to be supported for buffers created with any version of the
      wp_linux_dmabuf buffer factory. Version 2 additionally guarantees
      explicit synchronization support for opaque EGL buffers, which is a type
      of platform specific buffers described in the EGL_WL_bind_wayland_display
      extension. Compositors are free to support explicit synchronization for
      additional buffer types.
    
*/
class zwp_linux_surface_synchronization_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(int)> set_acquire_fence;
    std::function<void(zwp_linux_buffer_release_v1_t)> get_release;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_linux_surface_synchronization_v1_interface;
  static constexpr const unsigned int max_version = 2;

  friend class global_t<zwp_linux_surface_synchronization_v1_t>;
  friend class global_base_t;

public:
  zwp_linux_surface_synchronization_v1_t() = default;
  zwp_linux_surface_synchronization_v1_t(const client_t& client, uint32_t id, int version = 2);
  zwp_linux_surface_synchronization_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_linux_surface_synchronization_v1*() const;

  /** \brief destroy synchronization object

        Destroy this explicit synchronization object.

        Any fence set by this object with set_acquire_fence since the last
        commit will be discarded by the server. Any fences set by this object
        before the last commit are not affected.

        zwp_linux_buffer_release_v1 objects created by this object are not
        affected by this request.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set the acquire fence
      \param fd acquire fence fd

        Set the acquire fence that must be signaled before the compositor
        may sample from the buffer attached with wl_surface.attach. The fence
        is a dma_fence kernel object.

        The acquire fence is double-buffered state, and will be applied on the
        next wl_surface.commit request for the associated surface. Thus, it
        applies only to the buffer that is attached to the surface at commit
        time.

        If the provided fd is not a valid dma_fence fd, then an INVALID_FENCE
        error is raised.

        If a fence has already been attached during the same commit cycle, a
        DUPLICATE_FENCE error is raised.

        If the associated wl_surface was destroyed, a NO_SURFACE error is
        raised.

        If at surface commit time the attached buffer does not support explicit
        synchronization, an UNSUPPORTED_BUFFER error is raised.

        If at surface commit time there is no buffer attached, a NO_BUFFER
        error is raised.
      
  */
  std::function<void(int)> &on_set_acquire_fence();

  /** \brief release fence for last-attached buffer
      \param release new zwp_linux_buffer_release_v1 object

        Create a listener for the release of the buffer attached by the
        client with wl_surface.attach. See zwp_linux_buffer_release_v1
        documentation for more information.

        The release object is double-buffered state, and will be associated
        with the buffer that is attached to the surface at wl_surface.commit
        time.

        If a zwp_linux_buffer_release_v1 object has already been requested for
        the surface in the same commit cycle, a DUPLICATE_RELEASE error is
        raised.

        If the associated wl_surface was destroyed, a NO_SURFACE error
        is raised.

        If at surface commit time there is no buffer attached, a NO_BUFFER
        error is raised.
      
  */
  std::function<void(zwp_linux_buffer_release_v1_t)> &on_get_release();

  /** \brief Post error: the fence specified by the client could not be imported
  */
  void post_invalid_fence(std::string const& msg);

  /** \brief Post error: multiple fences added for a single surface commit
  */
  void post_duplicate_fence(std::string const& msg);

  /** \brief Post error: multiple releases added for a single surface commit
  */
  void post_duplicate_release(std::string const& msg);

  /** \brief Post error: the associated wl_surface was destroyed
  */
  void post_no_surface(std::string const& msg);

  /** \brief Post error: the buffer does not support explicit synchronization
  */
  void post_unsupported_buffer(std::string const& msg);

  /** \brief Post error: no buffer was attached
  */
  void post_no_buffer(std::string const& msg);

};

using global_zwp_linux_surface_synchronization_v1_t = global_t<zwp_linux_surface_synchronization_v1_t>;

/** \brief 

  */
enum class zwp_linux_surface_synchronization_v1_error : uint32_t
  {
  /** \brief the fence specified by the client could not be imported */
  invalid_fence = 0,
  /** \brief multiple fences added for a single surface commit */
  duplicate_fence = 1,
  /** \brief multiple releases added for a single surface commit */
  duplicate_release = 2,
  /** \brief the associated wl_surface was destroyed */
  no_surface = 3,
  /** \brief the buffer does not support explicit synchronization */
  unsupported_buffer = 4,
  /** \brief no buffer was attached */
  no_buffer = 5
};


/** \brief buffer release explicit synchronization

      This object is instantiated in response to a
      zwp_linux_surface_synchronization_v1.get_release request.

      It provides an alternative to wl_buffer.release events, providing a
      unique release from a single wl_surface.commit request. The release event
      also supports explicit synchronization, providing a fence FD for the
      client to synchronize against.

      Exactly one event, either a fenced_release or an immediate_release, will
      be emitted for the wl_surface.commit request. The compositor can choose
      release by release which event it uses.

      This event does not replace wl_buffer.release events; servers are still
      required to send those events.

      Once a buffer release object has delivered a 'fenced_release' or an
      'immediate_release' event it is automatically destroyed.
    
*/
class zwp_linux_buffer_release_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_linux_buffer_release_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_linux_buffer_release_v1_t>;
  friend class global_base_t;

public:
  zwp_linux_buffer_release_v1_t() = default;
  zwp_linux_buffer_release_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_linux_buffer_release_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_linux_buffer_release_v1*() const;

  /** \brief release buffer with fence
      \param fence fence for last operation on buffer

        Sent when the compositor has finalised its usage of the associated
        buffer for the relevant commit, providing a dma_fence which will be
        signaled when all operations by the compositor on that buffer for that
        commit have finished.

        Once the fence has signaled, and assuming the associated buffer is not
        pending release from other wl_surface.commit requests, no additional
        explicit or implicit synchronization is required to safely reuse or
        destroy the buffer.

        This event destroys the zwp_linux_buffer_release_v1 object.
      
  */
  void fenced_release(int fence, bool post = true);

  /** \brief Minimum protocol version required for the \ref fenced_release function
  */
  static constexpr std::uint32_t fenced_release_since_version = 1;

  /** \brief release buffer immediately

        Sent when the compositor has finalised its usage of the associated
        buffer for the relevant commit, and either performed no operations
        using it, or has a guarantee that all its operations on that buffer for
        that commit have finished.

        Once this event is received, and assuming the associated buffer is not
        pending release from other wl_surface.commit requests, no additional
        explicit or implicit synchronization is required to safely reuse or
        destroy the buffer.

        This event destroys the zwp_linux_buffer_release_v1 object.
      
  */
  void immediate_release(bool post = true);

  /** \brief Minimum protocol version required for the \ref immediate_release function
  */
  static constexpr std::uint32_t immediate_release_since_version = 1;

};

using global_zwp_linux_buffer_release_v1_t = global_t<zwp_linux_buffer_release_v1_t>;


/** \brief constrain the movement of a pointer

      The global interface exposing pointer constraining functionality. It
      exposes two requests: lock_pointer for locking the pointer to its
      position, and confine_pointer for locking the pointer to a region.

      The lock_pointer and confine_pointer requests create the objects
      wp_locked_pointer and wp_confined_pointer respectively, and the client can
      use these objects to interact with the lock.

      For any surface, only one lock or confinement may be active across all
      wl_pointer objects of the same seat. If a lock or confinement is requested
      when another lock or confinement is active or requested on the same surface
      and with any of the wl_pointer objects of the same seat, an
      'already_constrained' error will be raised.
    
*/
class zwp_pointer_constraints_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_locked_pointer_v1_t, surface_t, pointer_t, region_t, zwp_pointer_constraints_v1_lifetime)> lock_pointer;
    std::function<void(zwp_confined_pointer_v1_t, surface_t, pointer_t, region_t, zwp_pointer_constraints_v1_lifetime)> confine_pointer;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_pointer_constraints_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_pointer_constraints_v1_t>;
  friend class global_base_t;

public:
  zwp_pointer_constraints_v1_t() = default;
  zwp_pointer_constraints_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_pointer_constraints_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_pointer_constraints_v1*() const;

  /** \brief destroy the pointer constraints manager object

	Used by the client to notify the server that it will no longer use this
	pointer constraints object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief lock pointer to a position
      \param id 
      \param surface surface to lock pointer to
      \param pointer the pointer that should be locked
      \param region region of surface
      \param lifetime lock lifetime

	The lock_pointer request lets the client request to disable movements of
	the virtual pointer (i.e. the cursor), effectively locking the pointer
	to a position. This request may not take effect immediately; in the
	future, when the compositor deems implementation-specific constraints
	are satisfied, the pointer lock will be activated and the compositor
	sends a locked event.

	The protocol provides no guarantee that the constraints are ever
	satisfied, and does not require the compositor to send an error if the
	constraints cannot ever be satisfied. It is thus possible to request a
	lock that will never activate.

	There may not be another pointer constraint of any kind requested or
	active on the surface for any of the wl_pointer objects of the seat of
	the passed pointer when requesting a lock. If there is, an error will be
	raised. See general pointer lock documentation for more details.

	The intersection of the region passed with this request and the input
	region of the surface is used to determine where the pointer must be
	in order for the lock to activate. It is up to the compositor whether to
	warp the pointer or require some kind of user interaction for the lock
	to activate. If the region is null the surface input region is used.

	A surface may receive pointer focus without the lock being activated.

	The request creates a new object wp_locked_pointer which is used to
	interact with the lock as well as receive updates about its state. See
	the the description of wp_locked_pointer for further information.

	Note that while a pointer is locked, the wl_pointer objects of the
	corresponding seat will not emit any wl_pointer.motion events, but
	relative motion events will still be emitted via wp_relative_pointer
	objects of the same seat. wl_pointer.axis and wl_pointer.button events
	are unaffected.
      
  */
  std::function<void(zwp_locked_pointer_v1_t, surface_t, pointer_t, region_t, zwp_pointer_constraints_v1_lifetime)> &on_lock_pointer();

  /** \brief confine pointer to a region
      \param id 
      \param surface surface to lock pointer to
      \param pointer the pointer that should be confined
      \param region region of surface
      \param lifetime confinement lifetime

	The confine_pointer request lets the client request to confine the
	pointer cursor to a given region. This request may not take effect
	immediately; in the future, when the compositor deems implementation-
	specific constraints are satisfied, the pointer confinement will be
	activated and the compositor sends a confined event.

	The intersection of the region passed with this request and the input
	region of the surface is used to determine where the pointer must be
	in order for the confinement to activate. It is up to the compositor
	whether to warp the pointer or require some kind of user interaction for
	the confinement to activate. If the region is null the surface input
	region is used.

	The request will create a new object wp_confined_pointer which is used
	to interact with the confinement as well as receive updates about its
	state. See the the description of wp_confined_pointer for further
	information.
      
  */
  std::function<void(zwp_confined_pointer_v1_t, surface_t, pointer_t, region_t, zwp_pointer_constraints_v1_lifetime)> &on_confine_pointer();

  /** \brief Post error: pointer constraint already requested on that surface
  */
  void post_already_constrained(std::string const& msg);

};

using global_zwp_pointer_constraints_v1_t = global_t<zwp_pointer_constraints_v1_t>;

/** \brief wp_pointer_constraints error values

	These errors can be emitted in response to wp_pointer_constraints
	requests.
      
  */
enum class zwp_pointer_constraints_v1_error : uint32_t
  {
  /** \brief pointer constraint already requested on that surface */
  already_constrained = 1
};

/** \brief constraint lifetime

	These values represent different lifetime semantics. They are passed
	as arguments to the factory requests to specify how the constraint
	lifetimes should be managed.
      
  */
enum class zwp_pointer_constraints_v1_lifetime : uint32_t
  {
  oneshot = 1,
  persistent = 2
};


/** \brief receive relative pointer motion events

      The wp_locked_pointer interface represents a locked pointer state.

      While the lock of this object is active, the wl_pointer objects of the
      associated seat will not emit any wl_pointer.motion events.

      This object will send the event 'locked' when the lock is activated.
      Whenever the lock is activated, it is guaranteed that the locked surface
      will already have received pointer focus and that the pointer will be
      within the region passed to the request creating this object.

      To unlock the pointer, send the destroy request. This will also destroy
      the wp_locked_pointer object.

      If the compositor decides to unlock the pointer the unlocked event is
      sent. See wp_locked_pointer.unlock for details.

      When unlocking, the compositor may warp the cursor position to the set
      cursor position hint. If it does, it will not result in any relative
      motion events emitted via wp_relative_pointer.

      If the surface the lock was requested on is destroyed and the lock is not
      yet activated, the wp_locked_pointer object is now defunct and must be
      destroyed.
    
*/
class zwp_locked_pointer_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(double, double)> set_cursor_position_hint;
    std::function<void(region_t)> set_region;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_locked_pointer_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_locked_pointer_v1_t>;
  friend class global_base_t;

public:
  zwp_locked_pointer_v1_t() = default;
  zwp_locked_pointer_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_locked_pointer_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_locked_pointer_v1*() const;

  /** \brief destroy the locked pointer object

	Destroy the locked pointer object. If applicable, the compositor will
	unlock the pointer.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set the pointer cursor position hint
      \param surface_x surface-local x coordinate
      \param surface_y surface-local y coordinate

	Set the cursor position hint relative to the top left corner of the
	surface.

	If the client is drawing its own cursor, it should update the position
	hint to the position of its own cursor. A compositor may use this
	information to warp the pointer upon unlock in order to avoid pointer
	jumps.

	The cursor position hint is double buffered. The new hint will only take
	effect when the associated surface gets it pending state applied. See
	wl_surface.commit for details.
      
  */
  std::function<void(double, double)> &on_set_cursor_position_hint();

  /** \brief set a new lock region
      \param region region of surface

	Set a new region used to lock the pointer.

	The new lock region is double-buffered. The new lock region will
	only take effect when the associated surface gets its pending state
	applied. See wl_surface.commit for details.

	For details about the lock region, see wp_locked_pointer.
      
  */
  std::function<void(region_t)> &on_set_region();

  /** \brief lock activation event

	Notification that the pointer lock of the seat's pointer is activated.
      
  */
  void locked(bool post = true);

  /** \brief Minimum protocol version required for the \ref locked function
  */
  static constexpr std::uint32_t locked_since_version = 1;

  /** \brief lock deactivation event

	Notification that the pointer lock of the seat's pointer is no longer
	active. If this is a oneshot pointer lock (see
	wp_pointer_constraints.lifetime) this object is now defunct and should
	be destroyed. If this is a persistent pointer lock (see
	wp_pointer_constraints.lifetime) this pointer lock may again
	reactivate in the future.
      
  */
  void unlocked(bool post = true);

  /** \brief Minimum protocol version required for the \ref unlocked function
  */
  static constexpr std::uint32_t unlocked_since_version = 1;

};

using global_zwp_locked_pointer_v1_t = global_t<zwp_locked_pointer_v1_t>;


/** \brief confined pointer object

      The wp_confined_pointer interface represents a confined pointer state.

      This object will send the event 'confined' when the confinement is
      activated. Whenever the confinement is activated, it is guaranteed that
      the surface the pointer is confined to will already have received pointer
      focus and that the pointer will be within the region passed to the request
      creating this object. It is up to the compositor to decide whether this
      requires some user interaction and if the pointer will warp to within the
      passed region if outside.

      To unconfine the pointer, send the destroy request. This will also destroy
      the wp_confined_pointer object.

      If the compositor decides to unconfine the pointer the unconfined event is
      sent. The wp_confined_pointer object is at this point defunct and should
      be destroyed.
    
*/
class zwp_confined_pointer_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(region_t)> set_region;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_confined_pointer_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_confined_pointer_v1_t>;
  friend class global_base_t;

public:
  zwp_confined_pointer_v1_t() = default;
  zwp_confined_pointer_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_confined_pointer_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_confined_pointer_v1*() const;

  /** \brief destroy the confined pointer object

	Destroy the confined pointer object. If applicable, the compositor will
	unconfine the pointer.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set a new confine region
      \param region region of surface

	Set a new region used to confine the pointer.

	The new confine region is double-buffered. The new confine region will
	only take effect when the associated surface gets its pending state
	applied. See wl_surface.commit for details.

	If the confinement is active when the new confinement region is applied
	and the pointer ends up outside of newly applied region, the pointer may
	warped to a position within the new confinement region. If warped, a
	wl_pointer.motion event will be emitted, but no
	wp_relative_pointer.relative_motion event.

	The compositor may also, instead of using the new region, unconfine the
	pointer.

	For details about the confine region, see wp_confined_pointer.
      
  */
  std::function<void(region_t)> &on_set_region();

  /** \brief pointer confined

	Notification that the pointer confinement of the seat's pointer is
	activated.
      
  */
  void confined(bool post = true);

  /** \brief Minimum protocol version required for the \ref confined function
  */
  static constexpr std::uint32_t confined_since_version = 1;

  /** \brief pointer unconfined

	Notification that the pointer confinement of the seat's pointer is no
	longer active. If this is a oneshot pointer confinement (see
	wp_pointer_constraints.lifetime) this object is now defunct and should
	be destroyed. If this is a persistent pointer confinement (see
	wp_pointer_constraints.lifetime) this pointer confinement may again
	reactivate in the future.
      
  */
  void unconfined(bool post = true);

  /** \brief Minimum protocol version required for the \ref unconfined function
  */
  static constexpr std::uint32_t unconfined_since_version = 1;

};

using global_zwp_confined_pointer_v1_t = global_t<zwp_confined_pointer_v1_t>;


/** \brief touchpad gestures

      A global interface to provide semantic touchpad gestures for a given
      pointer.

      Three gestures are currently supported: swipe, pinch, and hold.
      Pinch and swipe gestures follow a three-stage cycle: begin, update,
      end, hold gestures follow a two-stage cycle: begin and end. All
      gestures are identified by a unique id.

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_pointer_gestures_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_pointer_gesture_swipe_v1_t, pointer_t)> get_swipe_gesture;
    std::function<void(zwp_pointer_gesture_pinch_v1_t, pointer_t)> get_pinch_gesture;
    std::function<void()> release;
    std::function<void(zwp_pointer_gesture_hold_v1_t, pointer_t)> get_hold_gesture;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_pointer_gestures_v1_interface;
  static constexpr const unsigned int max_version = 3;

  friend class global_t<zwp_pointer_gestures_v1_t>;
  friend class global_base_t;

public:
  zwp_pointer_gestures_v1_t() = default;
  zwp_pointer_gestures_v1_t(const client_t& client, uint32_t id, int version = 3);
  zwp_pointer_gestures_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_pointer_gestures_v1*() const;

  /** \brief get swipe gesture
      \param id 
      \param pointer 

	Create a swipe gesture object. See the
	wl_pointer_gesture_swipe interface for details.
      
  */
  std::function<void(zwp_pointer_gesture_swipe_v1_t, pointer_t)> &on_get_swipe_gesture();

  /** \brief get pinch gesture
      \param id 
      \param pointer 

	Create a pinch gesture object. See the
	wl_pointer_gesture_pinch interface for details.
      
  */
  std::function<void(zwp_pointer_gesture_pinch_v1_t, pointer_t)> &on_get_pinch_gesture();

  /** \brief destroy the pointer gesture object

	Destroy the pointer gesture object. Swipe, pinch and hold objects
	created via this gesture object remain valid.
      
  */
  std::function<void()> &on_release();

  /** \brief get hold gesture
      \param id 
      \param pointer 

	Create a hold gesture object. See the
	wl_pointer_gesture_hold interface for details.
      
  */
  std::function<void(zwp_pointer_gesture_hold_v1_t, pointer_t)> &on_get_hold_gesture();

};

using global_zwp_pointer_gestures_v1_t = global_t<zwp_pointer_gestures_v1_t>;


/** \brief a swipe gesture object

      A swipe gesture object notifies a client about a multi-finger swipe
      gesture detected on an indirect input device such as a touchpad.
      The gesture is usually initiated by multiple fingers moving in the
      same direction but once initiated the direction may change.
      The precise conditions of when such a gesture is detected are
      implementation-dependent.

      A gesture consists of three stages: begin, update (optional) and end.
      There cannot be multiple simultaneous hold, pinch or swipe gestures on a
      same pointer/seat, how compositors prevent these situations is
      implementation-dependent.

      A gesture may be cancelled by the compositor or the hardware.
      Clients should not consider performing permanent or irreversible
      actions until the end of a gesture has been received.
    
*/
class zwp_pointer_gesture_swipe_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_pointer_gesture_swipe_v1_interface;
  static constexpr const unsigned int max_version = 2;

  friend class global_t<zwp_pointer_gesture_swipe_v1_t>;
  friend class global_base_t;

public:
  zwp_pointer_gesture_swipe_v1_t() = default;
  zwp_pointer_gesture_swipe_v1_t(const client_t& client, uint32_t id, int version = 2);
  zwp_pointer_gesture_swipe_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_pointer_gesture_swipe_v1*() const;

  /** \brief destroy the pointer swipe gesture object

  */
  std::function<void()> &on_destroy();

  /** \brief multi-finger swipe begin
      \param serial 
      \param time timestamp with millisecond granularity
      \param surface 
      \param fingers number of fingers

	This event is sent when a multi-finger swipe gesture is detected
	on the device.
      
  */
  void begin(uint32_t serial, uint32_t time, surface_t const& surface, uint32_t fingers, bool post = true);

  /** \brief Minimum protocol version required for the \ref begin function
  */
  static constexpr std::uint32_t begin_since_version = 1;

  /** \brief multi-finger swipe motion
      \param time timestamp with millisecond granularity
      \param dx delta x coordinate in surface coordinate space
      \param dy delta y coordinate in surface coordinate space

	This event is sent when a multi-finger swipe gesture changes the
	position of the logical center.

	The dx and dy coordinates are relative coordinates of the logical
	center of the gesture compared to the previous event.
      
  */
  void update(uint32_t time, double dx, double dy, bool post = true);

  /** \brief Minimum protocol version required for the \ref update function
  */
  static constexpr std::uint32_t update_since_version = 1;

  /** \brief multi-finger swipe end
      \param serial 
      \param time timestamp with millisecond granularity
      \param cancelled 1 if the gesture was cancelled, 0 otherwise

	This event is sent when a multi-finger swipe gesture ceases to
	be valid. This may happen when one or more fingers are lifted or
	the gesture is cancelled.

	When a gesture is cancelled, the client should undo state changes
	caused by this gesture. What causes a gesture to be cancelled is
	implementation-dependent.
      
  */
  void end(uint32_t serial, uint32_t time, int32_t cancelled, bool post = true);

  /** \brief Minimum protocol version required for the \ref end function
  */
  static constexpr std::uint32_t end_since_version = 1;

};

using global_zwp_pointer_gesture_swipe_v1_t = global_t<zwp_pointer_gesture_swipe_v1_t>;


/** \brief a pinch gesture object

      A pinch gesture object notifies a client about a multi-finger pinch
      gesture detected on an indirect input device such as a touchpad.
      The gesture is usually initiated by multiple fingers moving towards
      each other or away from each other, or by two or more fingers rotating
      around a logical center of gravity. The precise conditions of when
      such a gesture is detected are implementation-dependent.

      A gesture consists of three stages: begin, update (optional) and end.
      There cannot be multiple simultaneous hold, pinch or swipe gestures on a
      same pointer/seat, how compositors prevent these situations is
      implementation-dependent.

      A gesture may be cancelled by the compositor or the hardware.
      Clients should not consider performing permanent or irreversible
      actions until the end of a gesture has been received.
    
*/
class zwp_pointer_gesture_pinch_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_pointer_gesture_pinch_v1_interface;
  static constexpr const unsigned int max_version = 2;

  friend class global_t<zwp_pointer_gesture_pinch_v1_t>;
  friend class global_base_t;

public:
  zwp_pointer_gesture_pinch_v1_t() = default;
  zwp_pointer_gesture_pinch_v1_t(const client_t& client, uint32_t id, int version = 2);
  zwp_pointer_gesture_pinch_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_pointer_gesture_pinch_v1*() const;

  /** \brief destroy the pinch gesture object

  */
  std::function<void()> &on_destroy();

  /** \brief multi-finger pinch begin
      \param serial 
      \param time timestamp with millisecond granularity
      \param surface 
      \param fingers number of fingers

	This event is sent when a multi-finger pinch gesture is detected
	on the device.
      
  */
  void begin(uint32_t serial, uint32_t time, surface_t const& surface, uint32_t fingers, bool post = true);

  /** \brief Minimum protocol version required for the \ref begin function
  */
  static constexpr std::uint32_t begin_since_version = 1;

  /** \brief multi-finger pinch motion
      \param time timestamp with millisecond granularity
      \param dx delta x coordinate in surface coordinate space
      \param dy delta y coordinate in surface coordinate space
      \param scale scale relative to the initial finger position
      \param rotation angle in degrees cw relative to the previous event

	This event is sent when a multi-finger pinch gesture changes the
	position of the logical center, the rotation or the relative scale.

	The dx and dy coordinates are relative coordinates in the
	surface coordinate space of the logical center of the gesture.

	The scale factor is an absolute scale compared to the
	pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers
	are now twice as far apart as on pointer_gesture_pinch.begin.

	The rotation is the relative angle in degrees clockwise compared to the previous
	pointer_gesture_pinch.begin or pointer_gesture_pinch.update event.
      
  */
  void update(uint32_t time, double dx, double dy, double scale, double rotation, bool post = true);

  /** \brief Minimum protocol version required for the \ref update function
  */
  static constexpr std::uint32_t update_since_version = 1;

  /** \brief multi-finger pinch end
      \param serial 
      \param time timestamp with millisecond granularity
      \param cancelled 1 if the gesture was cancelled, 0 otherwise

	This event is sent when a multi-finger pinch gesture ceases to
	be valid. This may happen when one or more fingers are lifted or
	the gesture is cancelled.

	When a gesture is cancelled, the client should undo state changes
	caused by this gesture. What causes a gesture to be cancelled is
	implementation-dependent.
      
  */
  void end(uint32_t serial, uint32_t time, int32_t cancelled, bool post = true);

  /** \brief Minimum protocol version required for the \ref end function
  */
  static constexpr std::uint32_t end_since_version = 1;

};

using global_zwp_pointer_gesture_pinch_v1_t = global_t<zwp_pointer_gesture_pinch_v1_t>;


/** \brief a hold gesture object

      A hold gesture object notifies a client about a single- or
      multi-finger hold gesture detected on an indirect input device such as
      a touchpad. The gesture is usually initiated by one or more fingers
      being held down without significant movement. The precise conditions
      of when such a gesture is detected are implementation-dependent.

      In particular, this gesture may be used to cancel kinetic scrolling.

      A hold gesture consists of two stages: begin and end. Unlike pinch and
      swipe there is no update stage.
      There cannot be multiple simultaneous hold, pinch or swipe gestures on a
      same pointer/seat, how compositors prevent these situations is
      implementation-dependent.

      A gesture may be cancelled by the compositor or the hardware.
      Clients should not consider performing permanent or irreversible
      actions until the end of a gesture has been received.
    
*/
class zwp_pointer_gesture_hold_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_pointer_gesture_hold_v1_interface;
  static constexpr const unsigned int max_version = 3;

  friend class global_t<zwp_pointer_gesture_hold_v1_t>;
  friend class global_base_t;

public:
  zwp_pointer_gesture_hold_v1_t() = default;
  zwp_pointer_gesture_hold_v1_t(const client_t& client, uint32_t id, int version = 3);
  zwp_pointer_gesture_hold_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_pointer_gesture_hold_v1*() const;

  /** \brief destroy the hold gesture object

  */
  std::function<void()> &on_destroy();

  /** \brief multi-finger hold begin
      \param serial 
      \param time timestamp with millisecond granularity
      \param surface 
      \param fingers number of fingers

	This event is sent when a hold gesture is detected on the device.
      
  */
  void begin(uint32_t serial, uint32_t time, surface_t const& surface, uint32_t fingers, bool post = true);

  /** \brief Minimum protocol version required for the \ref begin function
  */
  static constexpr std::uint32_t begin_since_version = 3;

  /** \brief Check whether the \ref begin function is available with
      the currently bound version of the protocol
  */
  bool can_begin() const;

  /** \brief multi-finger hold end
      \param serial 
      \param time timestamp with millisecond granularity
      \param cancelled 1 if the gesture was cancelled, 0 otherwise

	This event is sent when a hold gesture ceases to
	be valid. This may happen when the holding fingers are lifted or
	the gesture is cancelled, for example if the fingers move past an
	implementation-defined threshold, the finger count changes or the hold
	gesture changes into a different type of gesture.

	When a gesture is cancelled, the client may need to undo state changes
	caused by this gesture. What causes a gesture to be cancelled is
	implementation-dependent.
      
  */
  void end(uint32_t serial, uint32_t time, int32_t cancelled, bool post = true);

  /** \brief Minimum protocol version required for the \ref end function
  */
  static constexpr std::uint32_t end_since_version = 3;

  /** \brief Check whether the \ref end function is available with
      the currently bound version of the protocol
  */
  bool can_end() const;

};

using global_zwp_pointer_gesture_hold_v1_t = global_t<zwp_pointer_gesture_hold_v1_t>;


/** \brief X primary selection emulation

      The primary selection device manager is a singleton global object that
      provides access to the primary selection. It allows to create
      wp_primary_selection_source objects, as well as retrieving the per-seat
      wp_primary_selection_device objects.
    
*/
class zwp_primary_selection_device_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_primary_selection_source_v1_t)> create_source;
    std::function<void(zwp_primary_selection_device_v1_t, seat_t)> get_device;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_primary_selection_device_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_primary_selection_device_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_primary_selection_device_manager_v1_t() = default;
  zwp_primary_selection_device_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_primary_selection_device_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_primary_selection_device_manager_v1*() const;

  /** \brief create a new primary selection source
      \param id 

        Create a new primary selection source.
      
  */
  std::function<void(zwp_primary_selection_source_v1_t)> &on_create_source();

  /** \brief create a new primary selection device
      \param id 
      \param seat 

        Create a new data device for a given seat.
      
  */
  std::function<void(zwp_primary_selection_device_v1_t, seat_t)> &on_get_device();

  /** \brief destroy the primary selection device manager

        Destroy the primary selection device manager.
      
  */
  std::function<void()> &on_destroy();

};

using global_zwp_primary_selection_device_manager_v1_t = global_t<zwp_primary_selection_device_manager_v1_t>;


/** \brief 

*/
class zwp_primary_selection_device_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_primary_selection_source_v1_t, uint32_t)> set_selection;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_primary_selection_device_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_primary_selection_device_v1_t>;
  friend class global_base_t;

public:
  zwp_primary_selection_device_v1_t() = default;
  zwp_primary_selection_device_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_primary_selection_device_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_primary_selection_device_v1*() const;

  /** \brief set the primary selection
      \param source 
      \param serial serial of the event that triggered this request

        Replaces the current selection. The previous owner of the primary
        selection will receive a wp_primary_selection_source.cancelled event.

        To unset the selection, set the source to NULL.
      
  */
  std::function<void(zwp_primary_selection_source_v1_t, uint32_t)> &on_set_selection();

  /** \brief destroy the primary selection device

        Destroy the primary selection device.
      
  */
  std::function<void()> &on_destroy();

  /** \brief introduce a new wp_primary_selection_offer

        Introduces a new wp_primary_selection_offer object that may be used
        to receive the current primary selection. Immediately following this
        event, the new wp_primary_selection_offer object will send
        wp_primary_selection_offer.offer events to describe the offered mime
        types.
      
  */
  void data_offer(bool post = true);

  /** \brief Minimum protocol version required for the \ref data_offer function
  */
  static constexpr std::uint32_t data_offer_since_version = 1;

  /** \brief advertise a new primary selection
      \param id 

        The wp_primary_selection_device.selection event is sent to notify the
        client of a new primary selection. This event is sent after the
        wp_primary_selection.data_offer event introducing this object, and after
        the offer has announced its mimetypes through
        wp_primary_selection_offer.offer.

        The data_offer is valid until a new offer or NULL is received
        or until the client loses keyboard focus. The client must destroy the
        previous selection data_offer, if any, upon receiving this event.
      
  */
  void selection(zwp_primary_selection_offer_v1_t const& id, bool post = true);

  /** \brief Minimum protocol version required for the \ref selection function
  */
  static constexpr std::uint32_t selection_since_version = 1;

};

using global_zwp_primary_selection_device_v1_t = global_t<zwp_primary_selection_device_v1_t>;


/** \brief offer to transfer primary selection contents

      A wp_primary_selection_offer represents an offer to transfer the contents
      of the primary selection clipboard to the client. Similar to
      wl_data_offer, the offer also describes the mime types that the data can
      be converted to and provides the mechanisms for transferring the data
      directly to the client.
    
*/
class zwp_primary_selection_offer_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(std::string, int)> receive;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_primary_selection_offer_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_primary_selection_offer_v1_t>;
  friend class global_base_t;

public:
  zwp_primary_selection_offer_v1_t() = default;
  zwp_primary_selection_offer_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_primary_selection_offer_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_primary_selection_offer_v1*() const;

  /** \brief request that the data is transferred
      \param mime_type 
      \param fd 

        To transfer the contents of the primary selection clipboard, the client
        issues this request and indicates the mime type that it wants to
        receive. The transfer happens through the passed file descriptor
        (typically created with the pipe system call). The source client writes
        the data in the mime type representation requested and then closes the
        file descriptor.

        The receiving client reads from the read end of the pipe until EOF and
        closes its end, at which point the transfer is complete.
      
  */
  std::function<void(std::string, int)> &on_receive();

  /** \brief destroy the primary selection offer

        Destroy the primary selection offer.
      
  */
  std::function<void()> &on_destroy();

  /** \brief advertise offered mime type
      \param mime_type 

        Sent immediately after creating announcing the
        wp_primary_selection_offer through
        wp_primary_selection_device.data_offer. One event is sent per offered
        mime type.
      
  */
  void offer(std::string const& mime_type, bool post = true);

  /** \brief Minimum protocol version required for the \ref offer function
  */
  static constexpr std::uint32_t offer_since_version = 1;

};

using global_zwp_primary_selection_offer_v1_t = global_t<zwp_primary_selection_offer_v1_t>;


/** \brief offer to replace the contents of the primary selection

      The source side of a wp_primary_selection_offer, it provides a way to
      describe the offered data and respond to requests to transfer the
      requested contents of the primary selection clipboard.
    
*/
class zwp_primary_selection_source_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(std::string)> offer;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_primary_selection_source_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_primary_selection_source_v1_t>;
  friend class global_base_t;

public:
  zwp_primary_selection_source_v1_t() = default;
  zwp_primary_selection_source_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_primary_selection_source_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_primary_selection_source_v1*() const;

  /** \brief add an offered mime type
      \param mime_type 

        This request adds a mime type to the set of mime types advertised to
        targets. Can be called several times to offer multiple types.
      
  */
  std::function<void(std::string)> &on_offer();

  /** \brief destroy the primary selection source

        Destroy the primary selection source.
      
  */
  std::function<void()> &on_destroy();

  /** \brief send the primary selection contents
      \param mime_type 
      \param fd 

        Request for the current primary selection contents from the client.
        Send the specified mime type over the passed file descriptor, then
        close it.
      
  */
  void send(std::string const& mime_type, int fd, bool post = true);

  /** \brief Minimum protocol version required for the \ref send function
  */
  static constexpr std::uint32_t send_since_version = 1;

  /** \brief request for primary selection contents was canceled

        This primary selection source is no longer valid. The client should
        clean up and destroy this primary selection source.
      
  */
  void cancelled(bool post = true);

  /** \brief Minimum protocol version required for the \ref cancelled function
  */
  static constexpr std::uint32_t cancelled_since_version = 1;

};

using global_zwp_primary_selection_source_v1_t = global_t<zwp_primary_selection_source_v1_t>;


/** \brief get relative pointer objects

      A global interface used for getting the relative pointer object for a
      given pointer.
    
*/
class zwp_relative_pointer_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_relative_pointer_v1_t, pointer_t)> get_relative_pointer;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_relative_pointer_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_relative_pointer_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_relative_pointer_manager_v1_t() = default;
  zwp_relative_pointer_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_relative_pointer_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_relative_pointer_manager_v1*() const;

  /** \brief destroy the relative pointer manager object

	Used by the client to notify the server that it will no longer use this
	relative pointer manager object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief get a relative pointer object
      \param id 
      \param pointer 

	Create a relative pointer interface given a wl_pointer object. See the
	wp_relative_pointer interface for more details.
      
  */
  std::function<void(zwp_relative_pointer_v1_t, pointer_t)> &on_get_relative_pointer();

};

using global_zwp_relative_pointer_manager_v1_t = global_t<zwp_relative_pointer_manager_v1_t>;


/** \brief relative pointer object

      A wp_relative_pointer object is an extension to the wl_pointer interface
      used for emitting relative pointer events. It shares the same focus as
      wl_pointer objects of the same seat and will only emit events when it has
      focus.
    
*/
class zwp_relative_pointer_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_relative_pointer_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_relative_pointer_v1_t>;
  friend class global_base_t;

public:
  zwp_relative_pointer_v1_t() = default;
  zwp_relative_pointer_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_relative_pointer_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_relative_pointer_v1*() const;

  /** \brief release the relative pointer object

  */
  std::function<void()> &on_destroy();

  /** \brief relative pointer motion
      \param utime_hi high 32 bits of a 64 bit timestamp with microsecond granularity
      \param utime_lo low 32 bits of a 64 bit timestamp with microsecond granularity
      \param dx the x component of the motion vector
      \param dy the y component of the motion vector
      \param dx_unaccel the x component of the unaccelerated motion vector
      \param dy_unaccel the y component of the unaccelerated motion vector

	Relative x/y pointer motion from the pointer of the seat associated with
	this object.

	A relative motion is in the same dimension as regular wl_pointer motion
	events, except they do not represent an absolute position. For example,
	moving a pointer from (x, y) to (x', y') would have the equivalent
	relative motion (x' - x, y' - y). If a pointer motion caused the
	absolute pointer position to be clipped by for example the edge of the
	monitor, the relative motion is unaffected by the clipping and will
	represent the unclipped motion.

	This event also contains non-accelerated motion deltas. The
	non-accelerated delta is, when applicable, the regular pointer motion
	delta as it was before having applied motion acceleration and other
	transformations such as normalization.

	Note that the non-accelerated delta does not represent 'raw' events as
	they were read from some device. Pointer motion acceleration is device-
	and configuration-specific and non-accelerated deltas and accelerated
	deltas may have the same value on some devices.

	Relative motions are not coupled to wl_pointer.motion events, and can be
	sent in combination with such events, but also independently. There may
	also be scenarios where wl_pointer.motion is sent, but there is no
	relative motion. The order of an absolute and relative motion event
	originating from the same physical motion is not guaranteed.

	If the client needs button events or focus state, it can receive them
	from a wl_pointer object of the same seat that the wp_relative_pointer
	object is associated with.
      
  */
  void relative_motion(uint32_t utime_hi, uint32_t utime_lo, double dx, double dy, double dx_unaccel, double dy_unaccel, bool post = true);

  /** \brief Minimum protocol version required for the \ref relative_motion function
  */
  static constexpr std::uint32_t relative_motion_since_version = 1;

};

using global_zwp_relative_pointer_v1_t = global_t<zwp_relative_pointer_v1_t>;


/** \brief controller object for graphic tablet devices

      An object that provides access to the graphics tablets available on this
      system. All tablets are associated with a seat, to get access to the
      actual tablets, use wp_tablet_manager.get_tablet_seat.
    
*/
class zwp_tablet_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_tablet_seat_v1_t, seat_t)> get_tablet_seat;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_tablet_manager_v1_t() = default;
  zwp_tablet_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_manager_v1*() const;

  /** \brief get the tablet seat
      \param tablet_seat 
      \param seat The wl_seat object to retrieve the tablets for

	Get the wp_tablet_seat object for the given seat. This object
	provides access to all graphics tablets in this seat.
      
  */
  std::function<void(zwp_tablet_seat_v1_t, seat_t)> &on_get_tablet_seat();

  /** \brief release the memory for the tablet manager object

	Destroy the wp_tablet_manager object. Objects created from this
	object are unaffected and should be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

};

using global_zwp_tablet_manager_v1_t = global_t<zwp_tablet_manager_v1_t>;


/** \brief controller object for graphic tablet devices of a seat

      An object that provides access to the graphics tablets available on this
      seat. After binding to this interface, the compositor sends a set of
      wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events.
    
*/
class zwp_tablet_seat_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_seat_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_seat_v1_t>;
  friend class global_base_t;

public:
  zwp_tablet_seat_v1_t() = default;
  zwp_tablet_seat_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_seat_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_seat_v1*() const;

  /** \brief release the memory for the tablet seat object

	Destroy the wp_tablet_seat object. Objects created from this
	object are unaffected and should be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

  /** \brief new device notification
      \return the newly added graphics tablet

	This event is sent whenever a new tablet becomes available on this
	seat. This event only provides the object id of the tablet, any
	static information about the tablet (device name, vid/pid, etc.) is
	sent through the wp_tablet interface.
      
  */
  void tablet_added(bool post = true);

  /** \brief Minimum protocol version required for the \ref tablet_added function
  */
  static constexpr std::uint32_t tablet_added_since_version = 1;

  /** \brief a new tool has been used with a tablet
      \return the newly added tablet tool

	This event is sent whenever a tool that has not previously been used
	with a tablet comes into use. This event only provides the object id
	of the tool; any static information about the tool (capabilities,
	type, etc.) is sent through the wp_tablet_tool interface.
      
  */
  void tool_added(bool post = true);

  /** \brief Minimum protocol version required for the \ref tool_added function
  */
  static constexpr std::uint32_t tool_added_since_version = 1;

};

using global_zwp_tablet_seat_v1_t = global_t<zwp_tablet_seat_v1_t>;


/** \brief a physical tablet tool

      An object that represents a physical tool that has been, or is
      currently in use with a tablet in this seat. Each wp_tablet_tool
      object stays valid until the client destroys it; the compositor
      reuses the wp_tablet_tool object to indicate that the object's
      respective physical tool has come into proximity of a tablet again.

      A wp_tablet_tool object's relation to a physical tool depends on the
      tablet's ability to report serial numbers. If the tablet supports
      this capability, then the object represents a specific physical tool
      and can be identified even when used on multiple tablets.

      A tablet tool has a number of static characteristics, e.g. tool type,
      hardware_serial and capabilities. These capabilities are sent in an
      event sequence after the wp_tablet_seat.tool_added event before any
      actual events from this tool. This initial event sequence is
      terminated by a wp_tablet_tool.done event.

      Tablet tool events are grouped by wp_tablet_tool.frame events.
      Any events received before a wp_tablet_tool.frame event should be
      considered part of the same hardware state change.
    
*/
class zwp_tablet_tool_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(uint32_t, surface_t, int32_t, int32_t)> set_cursor;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_tool_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_tool_v1_t>;
  friend class global_base_t;

public:
  zwp_tablet_tool_v1_t() = default;
  zwp_tablet_tool_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_tool_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_tool_v1*() const;

  /** \brief set the tablet tool's surface
      \param serial serial of the enter event
      \param surface 
      \param hotspot_x surface-local x coordinate
      \param hotspot_y surface-local y coordinate

	Sets the surface of the cursor used for this tool on the given
	tablet. This request only takes effect if the tool is in proximity
	of one of the requesting client's surfaces or the surface parameter
	is the current pointer surface. If there was a previous surface set
	with this request it is replaced. If surface is NULL, the cursor
	image is hidden.

	The parameters hotspot_x and hotspot_y define the position of the
	pointer surface relative to the pointer location. Its top-left corner
	is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the
	coordinates of the pointer location, in surface-local coordinates.

	On surface.attach requests to the pointer surface, hotspot_x and
	hotspot_y are decremented by the x and y parameters passed to the
	request. Attach must be confirmed by wl_surface.commit as usual.

	The hotspot can also be updated by passing the currently set pointer
	surface to this request with new values for hotspot_x and hotspot_y.

	The current and pending input regions of the wl_surface are cleared,
	and wl_surface.set_input_region is ignored until the wl_surface is no
	longer used as the cursor. When the use as a cursor ends, the current
	and pending input regions become undefined, and the wl_surface is
	unmapped.

	This request gives the surface the role of a cursor. The role
	assigned by this request is the same as assigned by
	wl_pointer.set_cursor meaning the same surface can be
	used both as a wl_pointer cursor and a wp_tablet cursor. If the
	surface already has another role, it raises a protocol error.
	The surface may be used on multiple tablets and across multiple
	seats.
      
  */
  std::function<void(uint32_t, surface_t, int32_t, int32_t)> &on_set_cursor();

  /** \brief destroy the tool object

	This destroys the client's resource for this tool object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief tool type
      \param tool_type the physical tool type

	The tool type is the high-level type of the tool and usually decides
	the interaction expected from this tool.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void type(zwp_tablet_tool_v1_type const& tool_type, bool post = true);

  /** \brief Minimum protocol version required for the \ref type function
  */
  static constexpr std::uint32_t type_since_version = 1;

  /** \brief unique hardware serial number of the tool
      \param hardware_serial_hi the unique serial number of the tool, most significant bits
      \param hardware_serial_lo the unique serial number of the tool, least significant bits

	If the physical tool can be identified by a unique 64-bit serial
	number, this event notifies the client of this serial number.

	If multiple tablets are available in the same seat and the tool is
	uniquely identifiable by the serial number, that tool may move
	between tablets.

	Otherwise, if the tool has no serial number and this event is
	missing, the tool is tied to the tablet it first comes into
	proximity with. Even if the physical tool is used on multiple
	tablets, separate wp_tablet_tool objects will be created, one per
	tablet.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void hardware_serial(uint32_t hardware_serial_hi, uint32_t hardware_serial_lo, bool post = true);

  /** \brief Minimum protocol version required for the \ref hardware_serial function
  */
  static constexpr std::uint32_t hardware_serial_since_version = 1;

  /** \brief hardware id notification in Wacom's format
      \param hardware_id_hi the hardware id, most significant bits
      \param hardware_id_lo the hardware id, least significant bits

	This event notifies the client of a hardware id available on this tool.

	The hardware id is a device-specific 64-bit id that provides extra
	information about the tool in use, beyond the wl_tool.type
	enumeration. The format of the id is specific to tablets made by
	Wacom Inc. For example, the hardware id of a Wacom Grip
	Pen (a stylus) is 0x802.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void hardware_id_wacom(uint32_t hardware_id_hi, uint32_t hardware_id_lo, bool post = true);

  /** \brief Minimum protocol version required for the \ref hardware_id_wacom function
  */
  static constexpr std::uint32_t hardware_id_wacom_since_version = 1;

  /** \brief tool capability notification
      \param capability the capability

	This event notifies the client of any capabilities of this tool,
	beyond the main set of x/y axes and tip up/down detection.

	One event is sent for each extra capability available on this tool.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void capability(zwp_tablet_tool_v1_capability const& capability, bool post = true);

  /** \brief Minimum protocol version required for the \ref capability function
  */
  static constexpr std::uint32_t capability_since_version = 1;

  /** \brief tool description events sequence complete

	This event signals the end of the initial burst of descriptive
	events. A client may consider the static description of the tool to
	be complete and finalize initialization of the tool.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief tool removed

	This event is sent when the tool is removed from the system and will
	send no further events. Should the physical tool come back into
	proximity later, a new wp_tablet_tool object will be created.

	It is compositor-dependent when a tool is removed. A compositor may
	remove a tool on proximity out, tablet removal or any other reason.
	A compositor may also keep a tool alive until shutdown.

	If the tool is currently in proximity, a proximity_out event will be
	sent before the removed event. See wp_tablet_tool.proximity_out for
	the handling of any buttons logically down.

	When this event is received, the client must wp_tablet_tool.destroy
	the object.
      
  */
  void removed(bool post = true);

  /** \brief Minimum protocol version required for the \ref removed function
  */
  static constexpr std::uint32_t removed_since_version = 1;

  /** \brief proximity in event
      \param serial 
      \param tablet The tablet the tool is in proximity of
      \param surface The current surface the tablet tool is over

	Notification that this tool is focused on a certain surface.

	This event can be received when the tool has moved from one surface to
	another, or when the tool has come back into proximity above the
	surface.

	If any button is logically down when the tool comes into proximity,
	the respective button event is sent after the proximity_in event but
	within the same frame as the proximity_in event.
      
  */
  void proximity_in(uint32_t serial, zwp_tablet_v1_t const& tablet, surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref proximity_in function
  */
  static constexpr std::uint32_t proximity_in_since_version = 1;

  /** \brief proximity out event

	Notification that this tool has either left proximity, or is no
	longer focused on a certain surface.

	When the tablet tool leaves proximity of the tablet, button release
	events are sent for each button that was held down at the time of
	leaving proximity. These events are sent before the proximity_out
	event but within the same wp_tablet.frame.

	If the tool stays within proximity of the tablet, but the focus
	changes from one surface to another, a button release event may not
	be sent until the button is actually released or the tool leaves the
	proximity of the tablet.
      
  */
  void proximity_out(bool post = true);

  /** \brief Minimum protocol version required for the \ref proximity_out function
  */
  static constexpr std::uint32_t proximity_out_since_version = 1;

  /** \brief tablet tool is making contact
      \param serial 

	Sent whenever the tablet tool comes in contact with the surface of the
	tablet.

	If the tool is already in contact with the tablet when entering the
	input region, the client owning said region will receive a
	wp_tablet.proximity_in event, followed by a wp_tablet.down
	event and a wp_tablet.frame event.

	Note that this event describes logical contact, not physical
	contact. On some devices, a compositor may not consider a tool in
	logical contact until a minimum physical pressure threshold is
	exceeded.
      
  */
  void down(uint32_t serial, bool post = true);

  /** \brief Minimum protocol version required for the \ref down function
  */
  static constexpr std::uint32_t down_since_version = 1;

  /** \brief tablet tool is no longer making contact

	Sent whenever the tablet tool stops making contact with the surface of
	the tablet, or when the tablet tool moves out of the input region
	and the compositor grab (if any) is dismissed.

	If the tablet tool moves out of the input region while in contact
	with the surface of the tablet and the compositor does not have an
	ongoing grab on the surface, the client owning said region will
	receive a wp_tablet.up event, followed by a wp_tablet.proximity_out
	event and a wp_tablet.frame event. If the compositor has an ongoing
	grab on this device, this event sequence is sent whenever the grab
	is dismissed in the future.

	Note that this event describes logical contact, not physical
	contact. On some devices, a compositor may not consider a tool out
	of logical contact until physical pressure falls below a specific
	threshold.
      
  */
  void up(bool post = true);

  /** \brief Minimum protocol version required for the \ref up function
  */
  static constexpr std::uint32_t up_since_version = 1;

  /** \brief motion event
      \param x surface-local x coordinate
      \param y surface-local y coordinate

	Sent whenever a tablet tool moves.
      
  */
  void motion(double x, double y, bool post = true);

  /** \brief Minimum protocol version required for the \ref motion function
  */
  static constexpr std::uint32_t motion_since_version = 1;

  /** \brief pressure change event
      \param pressure The current pressure value

	Sent whenever the pressure axis on a tool changes. The value of this
	event is normalized to a value between 0 and 65535.

	Note that pressure may be nonzero even when a tool is not in logical
	contact. See the down and up events for more details.
      
  */
  void pressure(uint32_t pressure, bool post = true);

  /** \brief Minimum protocol version required for the \ref pressure function
  */
  static constexpr std::uint32_t pressure_since_version = 1;

  /** \brief distance change event
      \param distance The current distance value

	Sent whenever the distance axis on a tool changes. The value of this
	event is normalized to a value between 0 and 65535.

	Note that distance may be nonzero even when a tool is not in logical
	contact. See the down and up events for more details.
      
  */
  void distance(uint32_t distance, bool post = true);

  /** \brief Minimum protocol version required for the \ref distance function
  */
  static constexpr std::uint32_t distance_since_version = 1;

  /** \brief tilt change event
      \param tilt_x The current value of the X tilt axis
      \param tilt_y The current value of the Y tilt axis

	Sent whenever one or both of the tilt axes on a tool change. Each tilt
	value is in 0.01 of a degree, relative to the z-axis of the tablet.
	The angle is positive when the top of a tool tilts along the
	positive x or y axis.
      
  */
  void tilt(int32_t tilt_x, int32_t tilt_y, bool post = true);

  /** \brief Minimum protocol version required for the \ref tilt function
  */
  static constexpr std::uint32_t tilt_since_version = 1;

  /** \brief z-rotation change event
      \param degrees The current rotation of the Z axis

	Sent whenever the z-rotation axis on the tool changes. The
	rotation value is in 0.01 of a degree clockwise from the tool's
	logical neutral position.
      
  */
  void rotation(int32_t degrees, bool post = true);

  /** \brief Minimum protocol version required for the \ref rotation function
  */
  static constexpr std::uint32_t rotation_since_version = 1;

  /** \brief Slider position change event
      \param position The current position of slider

	Sent whenever the slider position on the tool changes. The
	value is normalized between -65535 and 65535, with 0 as the logical
	neutral position of the slider.

	The slider is available on e.g. the Wacom Airbrush tool.
      
  */
  void slider(int32_t position, bool post = true);

  /** \brief Minimum protocol version required for the \ref slider function
  */
  static constexpr std::uint32_t slider_since_version = 1;

  /** \brief Wheel delta event
      \param degrees The wheel delta in 0.01 of a degree
      \param clicks The wheel delta in discrete clicks

	Sent whenever the wheel on the tool emits an event. This event
	contains two values for the same axis change. The degrees value is
	in 0.01 of a degree in the same orientation as the
	wl_pointer.vertical_scroll axis. The clicks value is in discrete
	logical clicks of the mouse wheel. This value may be zero if the
	movement of the wheel was less than one logical click.

	Clients should choose either value and avoid mixing degrees and
	clicks. The compositor may accumulate values smaller than a logical
	click and emulate click events when a certain threshold is met.
	Thus, wl_tablet_tool.wheel events with non-zero clicks values may
	have different degrees values.
      
  */
  void wheel(int32_t degrees, int32_t clicks, bool post = true);

  /** \brief Minimum protocol version required for the \ref wheel function
  */
  static constexpr std::uint32_t wheel_since_version = 1;

  /** \brief button event
      \param serial 
      \param button The button whose state has changed
      \param state Whether the button was pressed or released

	Sent whenever a button on the tool is pressed or released.

	If a button is held down when the tool moves in or out of proximity,
	button events are generated by the compositor. See
	wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for
	details.
      
  */
  void button(uint32_t serial, uint32_t button, zwp_tablet_tool_v1_button_state const& state, bool post = true);

  /** \brief Minimum protocol version required for the \ref button function
  */
  static constexpr std::uint32_t button_since_version = 1;

  /** \brief frame event
      \param time The time of the event with millisecond granularity

	Marks the end of a series of axis and/or button updates from the
	tablet. The Wayland protocol requires axis updates to be sent
	sequentially, however all events within a frame should be considered
	one hardware event.
      
  */
  void frame(uint32_t time, bool post = true);

  /** \brief Minimum protocol version required for the \ref frame function
  */
  static constexpr std::uint32_t frame_since_version = 1;

  /** \brief Post error: given wl_surface has another role
  */
  void post_role(std::string const& msg);

};

using global_zwp_tablet_tool_v1_t = global_t<zwp_tablet_tool_v1_t>;

/** \brief a physical tool type

	Describes the physical type of a tool. The physical type of a tool
	generally defines its base usage.

	The mouse tool represents a mouse-shaped tool that is not a relative
	device but bound to the tablet's surface, providing absolute
	coordinates.

	The lens tool is a mouse-shaped tool with an attached lens to
	provide precision focus.
      
  */
enum class zwp_tablet_tool_v1_type : uint32_t
  {
  /** \brief Pen */
  pen = 0x140,
  /** \brief Eraser */
  eraser = 0x141,
  /** \brief Brush */
  brush = 0x142,
  /** \brief Pencil */
  pencil = 0x143,
  /** \brief Airbrush */
  airbrush = 0x144,
  /** \brief Finger */
  finger = 0x145,
  /** \brief Mouse */
  mouse = 0x146,
  /** \brief Lens */
  lens = 0x147
};

/** \brief capability flags for a tool

	Describes extra capabilities on a tablet.

	Any tool must provide x and y values, extra axes are
	device-specific.
      
  */
enum class zwp_tablet_tool_v1_capability : uint32_t
  {
  /** \brief Tilt axes */
  tilt = 1,
  /** \brief Pressure axis */
  pressure = 2,
  /** \brief Distance axis */
  distance = 3,
  /** \brief Z-rotation axis */
  rotation = 4,
  /** \brief Slider axis */
  slider = 5,
  /** \brief Wheel axis */
  wheel = 6
};

/** \brief physical button state

	Describes the physical state of a button that produced the button event.
      
  */
enum class zwp_tablet_tool_v1_button_state : uint32_t
  {
  /** \brief button is not pressed */
  released = 0,
  /** \brief button is pressed */
  pressed = 1
};

/** \brief 

  */
enum class zwp_tablet_tool_v1_error : uint32_t
  {
  /** \brief given wl_surface has another role */
  role = 0
};


/** \brief graphics tablet device

      The wp_tablet interface represents one graphics tablet device. The
      tablet interface itself does not generate events; all events are
      generated by wp_tablet_tool objects when in proximity above a tablet.

      A tablet has a number of static characteristics, e.g. device name and
      pid/vid. These capabilities are sent in an event sequence after the
      wp_tablet_seat.tablet_added event. This initial event sequence is
      terminated by a wp_tablet.done event.
    
*/
class zwp_tablet_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_v1_t>;
  friend class global_base_t;

public:
  zwp_tablet_v1_t() = default;
  zwp_tablet_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_v1*() const;

  /** \brief destroy the tablet object

	This destroys the client's resource for this tablet object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief tablet device name
      \param name the device name

	This event is sent in the initial burst of events before the
	wp_tablet.done event.
      
  */
  void name(std::string const& name, bool post = true);

  /** \brief Minimum protocol version required for the \ref name function
  */
  static constexpr std::uint32_t name_since_version = 1;

  /** \brief tablet device USB vendor/product id
      \param vid USB vendor id
      \param pid USB product id

	This event is sent in the initial burst of events before the
	wp_tablet.done event.
      
  */
  void id(uint32_t vid, uint32_t pid, bool post = true);

  /** \brief Minimum protocol version required for the \ref id function
  */
  static constexpr std::uint32_t id_since_version = 1;

  /** \brief path to the device
      \param path path to local device

	A system-specific device path that indicates which device is behind
	this wp_tablet. This information may be used to gather additional
	information about the device, e.g. through libwacom.

	A device may have more than one device path. If so, multiple
	wp_tablet.path events are sent. A device may be emulated and not
	have a device path, and in that case this event will not be sent.

	The format of the path is unspecified, it may be a device node, a
	sysfs path, or some other identifier. It is up to the client to
	identify the string provided.

	This event is sent in the initial burst of events before the
	wp_tablet.done event.
      
  */
  void path(std::string const& path, bool post = true);

  /** \brief Minimum protocol version required for the \ref path function
  */
  static constexpr std::uint32_t path_since_version = 1;

  /** \brief tablet description events sequence complete

	This event is sent immediately to signal the end of the initial
	burst of descriptive events. A client may consider the static
	description of the tablet to be complete and finalize initialization
	of the tablet.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief tablet removed event

	Sent when the tablet has been removed from the system. When a tablet
	is removed, some tools may be removed.

	When this event is received, the client must wp_tablet.destroy
	the object.
      
  */
  void removed(bool post = true);

  /** \brief Minimum protocol version required for the \ref removed function
  */
  static constexpr std::uint32_t removed_since_version = 1;

};

using global_zwp_tablet_v1_t = global_t<zwp_tablet_v1_t>;


/** \brief controller object for graphic tablet devices

      An object that provides access to the graphics tablets available on this
      system. All tablets are associated with a seat, to get access to the
      actual tablets, use wp_tablet_manager.get_tablet_seat.
    
*/
class zwp_tablet_manager_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_tablet_seat_v2_t, seat_t)> get_tablet_seat;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_manager_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_manager_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_manager_v2_t() = default;
  zwp_tablet_manager_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_manager_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_manager_v2*() const;

  /** \brief get the tablet seat
      \param tablet_seat 
      \param seat The wl_seat object to retrieve the tablets for

	Get the wp_tablet_seat object for the given seat. This object
	provides access to all graphics tablets in this seat.
      
  */
  std::function<void(zwp_tablet_seat_v2_t, seat_t)> &on_get_tablet_seat();

  /** \brief release the memory for the tablet manager object

	Destroy the wp_tablet_manager object. Objects created from this
	object are unaffected and should be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

};

using global_zwp_tablet_manager_v2_t = global_t<zwp_tablet_manager_v2_t>;


/** \brief controller object for graphic tablet devices of a seat

      An object that provides access to the graphics tablets available on this
      seat. After binding to this interface, the compositor sends a set of
      wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events.
    
*/
class zwp_tablet_seat_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_seat_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_seat_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_seat_v2_t() = default;
  zwp_tablet_seat_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_seat_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_seat_v2*() const;

  /** \brief release the memory for the tablet seat object

	Destroy the wp_tablet_seat object. Objects created from this
	object are unaffected and should be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

  /** \brief new device notification
      \return the newly added graphics tablet

	This event is sent whenever a new tablet becomes available on this
	seat. This event only provides the object id of the tablet, any
	static information about the tablet (device name, vid/pid, etc.) is
	sent through the wp_tablet interface.
      
  */
  void tablet_added(bool post = true);

  /** \brief Minimum protocol version required for the \ref tablet_added function
  */
  static constexpr std::uint32_t tablet_added_since_version = 1;

  /** \brief a new tool has been used with a tablet
      \return the newly added tablet tool

	This event is sent whenever a tool that has not previously been used
	with a tablet comes into use. This event only provides the object id
	of the tool; any static information about the tool (capabilities,
	type, etc.) is sent through the wp_tablet_tool interface.
      
  */
  void tool_added(bool post = true);

  /** \brief Minimum protocol version required for the \ref tool_added function
  */
  static constexpr std::uint32_t tool_added_since_version = 1;

  /** \brief new pad notification
      \return the newly added pad

	This event is sent whenever a new pad is known to the system. Typically,
	pads are physically attached to tablets and a pad_added event is
	sent immediately after the wp_tablet_seat.tablet_added.
	However, some standalone pad devices logically attach to tablets at
	runtime, and the client must wait for wp_tablet_pad.enter to know
	the tablet a pad is attached to.

	This event only provides the object id of the pad. All further
	features (buttons, strips, rings) are sent through the wp_tablet_pad
	interface.
      
  */
  void pad_added(bool post = true);

  /** \brief Minimum protocol version required for the \ref pad_added function
  */
  static constexpr std::uint32_t pad_added_since_version = 1;

};

using global_zwp_tablet_seat_v2_t = global_t<zwp_tablet_seat_v2_t>;


/** \brief a physical tablet tool

      An object that represents a physical tool that has been, or is
      currently in use with a tablet in this seat. Each wp_tablet_tool
      object stays valid until the client destroys it; the compositor
      reuses the wp_tablet_tool object to indicate that the object's
      respective physical tool has come into proximity of a tablet again.

      A wp_tablet_tool object's relation to a physical tool depends on the
      tablet's ability to report serial numbers. If the tablet supports
      this capability, then the object represents a specific physical tool
      and can be identified even when used on multiple tablets.

      A tablet tool has a number of static characteristics, e.g. tool type,
      hardware_serial and capabilities. These capabilities are sent in an
      event sequence after the wp_tablet_seat.tool_added event before any
      actual events from this tool. This initial event sequence is
      terminated by a wp_tablet_tool.done event.

      Tablet tool events are grouped by wp_tablet_tool.frame events.
      Any events received before a wp_tablet_tool.frame event should be
      considered part of the same hardware state change.
    
*/
class zwp_tablet_tool_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(uint32_t, surface_t, int32_t, int32_t)> set_cursor;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_tool_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_tool_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_tool_v2_t() = default;
  zwp_tablet_tool_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_tool_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_tool_v2*() const;

  /** \brief set the tablet tool's surface
      \param serial serial of the enter event
      \param surface 
      \param hotspot_x surface-local x coordinate
      \param hotspot_y surface-local y coordinate

	Sets the surface of the cursor used for this tool on the given
	tablet. This request only takes effect if the tool is in proximity
	of one of the requesting client's surfaces or the surface parameter
	is the current pointer surface. If there was a previous surface set
	with this request it is replaced. If surface is NULL, the cursor
	image is hidden.

	The parameters hotspot_x and hotspot_y define the position of the
	pointer surface relative to the pointer location. Its top-left corner
	is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the
	coordinates of the pointer location, in surface-local coordinates.

	On surface.attach requests to the pointer surface, hotspot_x and
	hotspot_y are decremented by the x and y parameters passed to the
	request. Attach must be confirmed by wl_surface.commit as usual.

	The hotspot can also be updated by passing the currently set pointer
	surface to this request with new values for hotspot_x and hotspot_y.

	The current and pending input regions of the wl_surface are cleared,
	and wl_surface.set_input_region is ignored until the wl_surface is no
	longer used as the cursor. When the use as a cursor ends, the current
	and pending input regions become undefined, and the wl_surface is
	unmapped.

	This request gives the surface the role of a wp_tablet_tool cursor. A
	surface may only ever be used as the cursor surface for one
	wp_tablet_tool. If the surface already has another role or has
	previously been used as cursor surface for a different tool, a
	protocol error is raised.
      
  */
  std::function<void(uint32_t, surface_t, int32_t, int32_t)> &on_set_cursor();

  /** \brief destroy the tool object

	This destroys the client's resource for this tool object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief tool type
      \param tool_type the physical tool type

	The tool type is the high-level type of the tool and usually decides
	the interaction expected from this tool.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void type(zwp_tablet_tool_v2_type const& tool_type, bool post = true);

  /** \brief Minimum protocol version required for the \ref type function
  */
  static constexpr std::uint32_t type_since_version = 1;

  /** \brief unique hardware serial number of the tool
      \param hardware_serial_hi the unique serial number of the tool, most significant bits
      \param hardware_serial_lo the unique serial number of the tool, least significant bits

	If the physical tool can be identified by a unique 64-bit serial
	number, this event notifies the client of this serial number.

	If multiple tablets are available in the same seat and the tool is
	uniquely identifiable by the serial number, that tool may move
	between tablets.

	Otherwise, if the tool has no serial number and this event is
	missing, the tool is tied to the tablet it first comes into
	proximity with. Even if the physical tool is used on multiple
	tablets, separate wp_tablet_tool objects will be created, one per
	tablet.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void hardware_serial(uint32_t hardware_serial_hi, uint32_t hardware_serial_lo, bool post = true);

  /** \brief Minimum protocol version required for the \ref hardware_serial function
  */
  static constexpr std::uint32_t hardware_serial_since_version = 1;

  /** \brief hardware id notification in Wacom's format
      \param hardware_id_hi the hardware id, most significant bits
      \param hardware_id_lo the hardware id, least significant bits

	This event notifies the client of a hardware id available on this tool.

	The hardware id is a device-specific 64-bit id that provides extra
	information about the tool in use, beyond the wl_tool.type
	enumeration. The format of the id is specific to tablets made by
	Wacom Inc. For example, the hardware id of a Wacom Grip
	Pen (a stylus) is 0x802.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void hardware_id_wacom(uint32_t hardware_id_hi, uint32_t hardware_id_lo, bool post = true);

  /** \brief Minimum protocol version required for the \ref hardware_id_wacom function
  */
  static constexpr std::uint32_t hardware_id_wacom_since_version = 1;

  /** \brief tool capability notification
      \param capability the capability

	This event notifies the client of any capabilities of this tool,
	beyond the main set of x/y axes and tip up/down detection.

	One event is sent for each extra capability available on this tool.

	This event is sent in the initial burst of events before the
	wp_tablet_tool.done event.
      
  */
  void capability(zwp_tablet_tool_v2_capability const& capability, bool post = true);

  /** \brief Minimum protocol version required for the \ref capability function
  */
  static constexpr std::uint32_t capability_since_version = 1;

  /** \brief tool description events sequence complete

	This event signals the end of the initial burst of descriptive
	events. A client may consider the static description of the tool to
	be complete and finalize initialization of the tool.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief tool removed

	This event is sent when the tool is removed from the system and will
	send no further events. Should the physical tool come back into
	proximity later, a new wp_tablet_tool object will be created.

	It is compositor-dependent when a tool is removed. A compositor may
	remove a tool on proximity out, tablet removal or any other reason.
	A compositor may also keep a tool alive until shutdown.

	If the tool is currently in proximity, a proximity_out event will be
	sent before the removed event. See wp_tablet_tool.proximity_out for
	the handling of any buttons logically down.

	When this event is received, the client must wp_tablet_tool.destroy
	the object.
      
  */
  void removed(bool post = true);

  /** \brief Minimum protocol version required for the \ref removed function
  */
  static constexpr std::uint32_t removed_since_version = 1;

  /** \brief proximity in event
      \param serial 
      \param tablet The tablet the tool is in proximity of
      \param surface The current surface the tablet tool is over

	Notification that this tool is focused on a certain surface.

	This event can be received when the tool has moved from one surface to
	another, or when the tool has come back into proximity above the
	surface.

	If any button is logically down when the tool comes into proximity,
	the respective button event is sent after the proximity_in event but
	within the same frame as the proximity_in event.
      
  */
  void proximity_in(uint32_t serial, zwp_tablet_v2_t const& tablet, surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref proximity_in function
  */
  static constexpr std::uint32_t proximity_in_since_version = 1;

  /** \brief proximity out event

	Notification that this tool has either left proximity, or is no
	longer focused on a certain surface.

	When the tablet tool leaves proximity of the tablet, button release
	events are sent for each button that was held down at the time of
	leaving proximity. These events are sent before the proximity_out
	event but within the same wp_tablet.frame.

	If the tool stays within proximity of the tablet, but the focus
	changes from one surface to another, a button release event may not
	be sent until the button is actually released or the tool leaves the
	proximity of the tablet.
      
  */
  void proximity_out(bool post = true);

  /** \brief Minimum protocol version required for the \ref proximity_out function
  */
  static constexpr std::uint32_t proximity_out_since_version = 1;

  /** \brief tablet tool is making contact
      \param serial 

	Sent whenever the tablet tool comes in contact with the surface of the
	tablet.

	If the tool is already in contact with the tablet when entering the
	input region, the client owning said region will receive a
	wp_tablet.proximity_in event, followed by a wp_tablet.down
	event and a wp_tablet.frame event.

	Note that this event describes logical contact, not physical
	contact. On some devices, a compositor may not consider a tool in
	logical contact until a minimum physical pressure threshold is
	exceeded.
      
  */
  void down(uint32_t serial, bool post = true);

  /** \brief Minimum protocol version required for the \ref down function
  */
  static constexpr std::uint32_t down_since_version = 1;

  /** \brief tablet tool is no longer making contact

	Sent whenever the tablet tool stops making contact with the surface of
	the tablet, or when the tablet tool moves out of the input region
	and the compositor grab (if any) is dismissed.

	If the tablet tool moves out of the input region while in contact
	with the surface of the tablet and the compositor does not have an
	ongoing grab on the surface, the client owning said region will
	receive a wp_tablet.up event, followed by a wp_tablet.proximity_out
	event and a wp_tablet.frame event. If the compositor has an ongoing
	grab on this device, this event sequence is sent whenever the grab
	is dismissed in the future.

	Note that this event describes logical contact, not physical
	contact. On some devices, a compositor may not consider a tool out
	of logical contact until physical pressure falls below a specific
	threshold.
      
  */
  void up(bool post = true);

  /** \brief Minimum protocol version required for the \ref up function
  */
  static constexpr std::uint32_t up_since_version = 1;

  /** \brief motion event
      \param x surface-local x coordinate
      \param y surface-local y coordinate

	Sent whenever a tablet tool moves.
      
  */
  void motion(double x, double y, bool post = true);

  /** \brief Minimum protocol version required for the \ref motion function
  */
  static constexpr std::uint32_t motion_since_version = 1;

  /** \brief pressure change event
      \param pressure The current pressure value

	Sent whenever the pressure axis on a tool changes. The value of this
	event is normalized to a value between 0 and 65535.

	Note that pressure may be nonzero even when a tool is not in logical
	contact. See the down and up events for more details.
      
  */
  void pressure(uint32_t pressure, bool post = true);

  /** \brief Minimum protocol version required for the \ref pressure function
  */
  static constexpr std::uint32_t pressure_since_version = 1;

  /** \brief distance change event
      \param distance The current distance value

	Sent whenever the distance axis on a tool changes. The value of this
	event is normalized to a value between 0 and 65535.

	Note that distance may be nonzero even when a tool is not in logical
	contact. See the down and up events for more details.
      
  */
  void distance(uint32_t distance, bool post = true);

  /** \brief Minimum protocol version required for the \ref distance function
  */
  static constexpr std::uint32_t distance_since_version = 1;

  /** \brief tilt change event
      \param tilt_x The current value of the X tilt axis
      \param tilt_y The current value of the Y tilt axis

	Sent whenever one or both of the tilt axes on a tool change. Each tilt
	value is in degrees, relative to the z-axis of the tablet.
	The angle is positive when the top of a tool tilts along the
	positive x or y axis.
      
  */
  void tilt(double tilt_x, double tilt_y, bool post = true);

  /** \brief Minimum protocol version required for the \ref tilt function
  */
  static constexpr std::uint32_t tilt_since_version = 1;

  /** \brief z-rotation change event
      \param degrees The current rotation of the Z axis

	Sent whenever the z-rotation axis on the tool changes. The
	rotation value is in degrees clockwise from the tool's
	logical neutral position.
      
  */
  void rotation(double degrees, bool post = true);

  /** \brief Minimum protocol version required for the \ref rotation function
  */
  static constexpr std::uint32_t rotation_since_version = 1;

  /** \brief Slider position change event
      \param position The current position of slider

	Sent whenever the slider position on the tool changes. The
	value is normalized between -65535 and 65535, with 0 as the logical
	neutral position of the slider.

	The slider is available on e.g. the Wacom Airbrush tool.
      
  */
  void slider(int32_t position, bool post = true);

  /** \brief Minimum protocol version required for the \ref slider function
  */
  static constexpr std::uint32_t slider_since_version = 1;

  /** \brief Wheel delta event
      \param degrees The wheel delta in degrees
      \param clicks The wheel delta in discrete clicks

	Sent whenever the wheel on the tool emits an event. This event
	contains two values for the same axis change. The degrees value is
	in the same orientation as the wl_pointer.vertical_scroll axis. The
	clicks value is in discrete logical clicks of the mouse wheel. This
	value may be zero if the movement of the wheel was less
	than one logical click.

	Clients should choose either value and avoid mixing degrees and
	clicks. The compositor may accumulate values smaller than a logical
	click and emulate click events when a certain threshold is met.
	Thus, wl_tablet_tool.wheel events with non-zero clicks values may
	have different degrees values.
      
  */
  void wheel(double degrees, int32_t clicks, bool post = true);

  /** \brief Minimum protocol version required for the \ref wheel function
  */
  static constexpr std::uint32_t wheel_since_version = 1;

  /** \brief button event
      \param serial 
      \param button The button whose state has changed
      \param state Whether the button was pressed or released

	Sent whenever a button on the tool is pressed or released.

	If a button is held down when the tool moves in or out of proximity,
	button events are generated by the compositor. See
	wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for
	details.
      
  */
  void button(uint32_t serial, uint32_t button, zwp_tablet_tool_v2_button_state const& state, bool post = true);

  /** \brief Minimum protocol version required for the \ref button function
  */
  static constexpr std::uint32_t button_since_version = 1;

  /** \brief frame event
      \param time The time of the event with millisecond granularity

	Marks the end of a series of axis and/or button updates from the
	tablet. The Wayland protocol requires axis updates to be sent
	sequentially, however all events within a frame should be considered
	one hardware event.
      
  */
  void frame(uint32_t time, bool post = true);

  /** \brief Minimum protocol version required for the \ref frame function
  */
  static constexpr std::uint32_t frame_since_version = 1;

  /** \brief Post error: given wl_surface has another role
  */
  void post_role(std::string const& msg);

};

using global_zwp_tablet_tool_v2_t = global_t<zwp_tablet_tool_v2_t>;

/** \brief a physical tool type

	Describes the physical type of a tool. The physical type of a tool
	generally defines its base usage.

	The mouse tool represents a mouse-shaped tool that is not a relative
	device but bound to the tablet's surface, providing absolute
	coordinates.

	The lens tool is a mouse-shaped tool with an attached lens to
	provide precision focus.
      
  */
enum class zwp_tablet_tool_v2_type : uint32_t
  {
  /** \brief Pen */
  pen = 0x140,
  /** \brief Eraser */
  eraser = 0x141,
  /** \brief Brush */
  brush = 0x142,
  /** \brief Pencil */
  pencil = 0x143,
  /** \brief Airbrush */
  airbrush = 0x144,
  /** \brief Finger */
  finger = 0x145,
  /** \brief Mouse */
  mouse = 0x146,
  /** \brief Lens */
  lens = 0x147
};

/** \brief capability flags for a tool

	Describes extra capabilities on a tablet.

	Any tool must provide x and y values, extra axes are
	device-specific.
      
  */
enum class zwp_tablet_tool_v2_capability : uint32_t
  {
  /** \brief Tilt axes */
  tilt = 1,
  /** \brief Pressure axis */
  pressure = 2,
  /** \brief Distance axis */
  distance = 3,
  /** \brief Z-rotation axis */
  rotation = 4,
  /** \brief Slider axis */
  slider = 5,
  /** \brief Wheel axis */
  wheel = 6
};

/** \brief physical button state

	Describes the physical state of a button that produced the button event.
      
  */
enum class zwp_tablet_tool_v2_button_state : uint32_t
  {
  /** \brief button is not pressed */
  released = 0,
  /** \brief button is pressed */
  pressed = 1
};

/** \brief 

  */
enum class zwp_tablet_tool_v2_error : uint32_t
  {
  /** \brief given wl_surface has another role */
  role = 0
};


/** \brief graphics tablet device

      The wp_tablet interface represents one graphics tablet device. The
      tablet interface itself does not generate events; all events are
      generated by wp_tablet_tool objects when in proximity above a tablet.

      A tablet has a number of static characteristics, e.g. device name and
      pid/vid. These capabilities are sent in an event sequence after the
      wp_tablet_seat.tablet_added event. This initial event sequence is
      terminated by a wp_tablet.done event.
    
*/
class zwp_tablet_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_v2_t() = default;
  zwp_tablet_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_v2*() const;

  /** \brief destroy the tablet object

	This destroys the client's resource for this tablet object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief tablet device name
      \param name the device name

	This event is sent in the initial burst of events before the
	wp_tablet.done event.
      
  */
  void name(std::string const& name, bool post = true);

  /** \brief Minimum protocol version required for the \ref name function
  */
  static constexpr std::uint32_t name_since_version = 1;

  /** \brief tablet device USB vendor/product id
      \param vid USB vendor id
      \param pid USB product id

	This event is sent in the initial burst of events before the
	wp_tablet.done event.
      
  */
  void id(uint32_t vid, uint32_t pid, bool post = true);

  /** \brief Minimum protocol version required for the \ref id function
  */
  static constexpr std::uint32_t id_since_version = 1;

  /** \brief path to the device
      \param path path to local device

	A system-specific device path that indicates which device is behind
	this wp_tablet. This information may be used to gather additional
	information about the device, e.g. through libwacom.

	A device may have more than one device path. If so, multiple
	wp_tablet.path events are sent. A device may be emulated and not
	have a device path, and in that case this event will not be sent.

	The format of the path is unspecified, it may be a device node, a
	sysfs path, or some other identifier. It is up to the client to
	identify the string provided.

	This event is sent in the initial burst of events before the
	wp_tablet.done event.
      
  */
  void path(std::string const& path, bool post = true);

  /** \brief Minimum protocol version required for the \ref path function
  */
  static constexpr std::uint32_t path_since_version = 1;

  /** \brief tablet description events sequence complete

	This event is sent immediately to signal the end of the initial
	burst of descriptive events. A client may consider the static
	description of the tablet to be complete and finalize initialization
	of the tablet.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief tablet removed event

	Sent when the tablet has been removed from the system. When a tablet
	is removed, some tools may be removed.

	When this event is received, the client must wp_tablet.destroy
	the object.
      
  */
  void removed(bool post = true);

  /** \brief Minimum protocol version required for the \ref removed function
  */
  static constexpr std::uint32_t removed_since_version = 1;

};

using global_zwp_tablet_v2_t = global_t<zwp_tablet_v2_t>;


/** \brief pad ring

      A circular interaction area, such as the touch ring on the Wacom Intuos
      Pro series tablets.

      Events on a ring are logically grouped by the wl_tablet_pad_ring.frame
      event.
    
*/
class zwp_tablet_pad_ring_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(std::string, uint32_t)> set_feedback;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_pad_ring_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_pad_ring_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_pad_ring_v2_t() = default;
  zwp_tablet_pad_ring_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_pad_ring_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_pad_ring_v2*() const;

  /** \brief set compositor feedback
      \param description ring description
      \param serial serial of the mode switch event

	Request that the compositor use the provided feedback string
	associated with this ring. This request should be issued immediately
	after a wp_tablet_pad_group.mode_switch event from the corresponding
	group is received, or whenever the ring is mapped to a different
	action. See wp_tablet_pad_group.mode_switch for more details.

	Clients are encouraged to provide context-aware descriptions for
	the actions associated with the ring; compositors may use this
	information to offer visual feedback about the button layout
	(eg. on-screen displays).

	The provided string 'description' is a UTF-8 encoded string to be
	associated with this ring, and is considered user-visible; general
	internationalization rules apply.

	The serial argument will be that of the last
	wp_tablet_pad_group.mode_switch event received for the group of this
	ring. Requests providing other serials than the most recent one will be
	ignored.
      
  */
  std::function<void(std::string, uint32_t)> &on_set_feedback();

  /** \brief destroy the ring object

	This destroys the client's resource for this ring object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief ring event source
      \param source the event source

	Source information for ring events.

	This event does not occur on its own. It is sent before a
	wp_tablet_pad_ring.frame event and carries the source information
	for all events within that frame.

	The source specifies how this event was generated. If the source is
	wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event
	will be sent when the user lifts the finger off the device.

	This event is optional. If the source is unknown for an interaction,
	no event is sent.
      
  */
  void source(zwp_tablet_pad_ring_v2_source const& source, bool post = true);

  /** \brief Minimum protocol version required for the \ref source function
  */
  static constexpr std::uint32_t source_since_version = 1;

  /** \brief angle changed
      \param degrees the current angle in degrees

	Sent whenever the angle on a ring changes.

	The angle is provided in degrees clockwise from the logical
	north of the ring in the pad's current rotation.
      
  */
  void angle(double degrees, bool post = true);

  /** \brief Minimum protocol version required for the \ref angle function
  */
  static constexpr std::uint32_t angle_since_version = 1;

  /** \brief interaction stopped

	Stop notification for ring events.

	For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop
	event is sent to notify a client that the interaction with the ring
	has terminated. This enables the client to implement kinetic scrolling.
	See the wp_tablet_pad_ring.source documentation for information on
	when this event may be generated.

	Any wp_tablet_pad_ring.angle events with the same source after this
	event should be considered as the start of a new interaction.
      
  */
  void stop(bool post = true);

  /** \brief Minimum protocol version required for the \ref stop function
  */
  static constexpr std::uint32_t stop_since_version = 1;

  /** \brief end of a ring event sequence
      \param time timestamp with millisecond granularity

	Indicates the end of a set of ring events that logically belong
	together. A client is expected to accumulate the data in all events
	within the frame before proceeding.

	All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong
	logically together. For example, on termination of a finger interaction
	on a ring the compositor will send a wp_tablet_pad_ring.source event,
	a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event.

	A wp_tablet_pad_ring.frame event is sent for every logical event
	group, even if the group only contains a single wp_tablet_pad_ring
	event. Specifically, a client may get a sequence: angle, frame,
	angle, frame, etc.
      
  */
  void frame(uint32_t time, bool post = true);

  /** \brief Minimum protocol version required for the \ref frame function
  */
  static constexpr std::uint32_t frame_since_version = 1;

};

using global_zwp_tablet_pad_ring_v2_t = global_t<zwp_tablet_pad_ring_v2_t>;

/** \brief ring axis source

	Describes the source types for ring events. This indicates to the
	client how a ring event was physically generated; a client may
	adjust the user interface accordingly. For example, events
	from a "finger" source may trigger kinetic scrolling.
      
  */
enum class zwp_tablet_pad_ring_v2_source : uint32_t
  {
  /** \brief finger */
  finger = 1
};


/** \brief pad strip

      A linear interaction area, such as the strips found in Wacom Cintiq
      models.

      Events on a strip are logically grouped by the wl_tablet_pad_strip.frame
      event.
    
*/
class zwp_tablet_pad_strip_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(std::string, uint32_t)> set_feedback;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_pad_strip_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_pad_strip_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_pad_strip_v2_t() = default;
  zwp_tablet_pad_strip_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_pad_strip_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_pad_strip_v2*() const;

  /** \brief set compositor feedback
      \param description strip description
      \param serial serial of the mode switch event

	Requests the compositor to use the provided feedback string
	associated with this strip. This request should be issued immediately
	after a wp_tablet_pad_group.mode_switch event from the corresponding
	group is received, or whenever the strip is mapped to a different
	action. See wp_tablet_pad_group.mode_switch for more details.

	Clients are encouraged to provide context-aware descriptions for
	the actions associated with the strip, and compositors may use this
	information to offer visual feedback about the button layout
	(eg. on-screen displays).

	The provided string 'description' is a UTF-8 encoded string to be
	associated with this ring, and is considered user-visible; general
	internationalization rules apply.

	The serial argument will be that of the last
	wp_tablet_pad_group.mode_switch event received for the group of this
	strip. Requests providing other serials than the most recent one will be
	ignored.
      
  */
  std::function<void(std::string, uint32_t)> &on_set_feedback();

  /** \brief destroy the strip object

	This destroys the client's resource for this strip object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief strip event source
      \param source the event source

	Source information for strip events.

	This event does not occur on its own. It is sent before a
	wp_tablet_pad_strip.frame event and carries the source information
	for all events within that frame.

	The source specifies how this event was generated. If the source is
	wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event
	will be sent when the user lifts their finger off the device.

	This event is optional. If the source is unknown for an interaction,
	no event is sent.
      
  */
  void source(zwp_tablet_pad_strip_v2_source const& source, bool post = true);

  /** \brief Minimum protocol version required for the \ref source function
  */
  static constexpr std::uint32_t source_since_version = 1;

  /** \brief position changed
      \param position the current position

	Sent whenever the position on a strip changes.

	The position is normalized to a range of [0, 65535], the 0-value
	represents the top-most and/or left-most position of the strip in
	the pad's current rotation.
      
  */
  void position(uint32_t position, bool post = true);

  /** \brief Minimum protocol version required for the \ref position function
  */
  static constexpr std::uint32_t position_since_version = 1;

  /** \brief interaction stopped

	Stop notification for strip events.

	For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop
	event is sent to notify a client that the interaction with the strip
	has terminated. This enables the client to implement kinetic
	scrolling. See the wp_tablet_pad_strip.source documentation for
	information on when this event may be generated.

	Any wp_tablet_pad_strip.position events with the same source after this
	event should be considered as the start of a new interaction.
      
  */
  void stop(bool post = true);

  /** \brief Minimum protocol version required for the \ref stop function
  */
  static constexpr std::uint32_t stop_since_version = 1;

  /** \brief end of a strip event sequence
      \param time timestamp with millisecond granularity

	Indicates the end of a set of events that represent one logical
	hardware strip event. A client is expected to accumulate the data
	in all events within the frame before proceeding.

	All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong
	logically together. For example, on termination of a finger interaction
	on a strip the compositor will send a wp_tablet_pad_strip.source event,
	a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame
	event.

	A wp_tablet_pad_strip.frame event is sent for every logical event
	group, even if the group only contains a single wp_tablet_pad_strip
	event. Specifically, a client may get a sequence: position, frame,
	position, frame, etc.
      
  */
  void frame(uint32_t time, bool post = true);

  /** \brief Minimum protocol version required for the \ref frame function
  */
  static constexpr std::uint32_t frame_since_version = 1;

};

using global_zwp_tablet_pad_strip_v2_t = global_t<zwp_tablet_pad_strip_v2_t>;

/** \brief strip axis source

	Describes the source types for strip events. This indicates to the
	client how a strip event was physically generated; a client may
	adjust the user interface accordingly. For example, events
	from a "finger" source may trigger kinetic scrolling.
      
  */
enum class zwp_tablet_pad_strip_v2_source : uint32_t
  {
  /** \brief finger */
  finger = 1
};


/** \brief a set of buttons, rings and strips

      A pad group describes a distinct (sub)set of buttons, rings and strips
      present in the tablet. The criteria of this grouping is usually positional,
      eg. if a tablet has buttons on the left and right side, 2 groups will be
      presented. The physical arrangement of groups is undisclosed and may
      change on the fly.

      Pad groups will announce their features during pad initialization. Between
      the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the
      pad group will announce the buttons, rings and strips contained in it,
      plus the number of supported modes.

      Modes are a mechanism to allow multiple groups of actions for every element
      in the pad group. The number of groups and available modes in each is
      persistent across device plugs. The current mode is user-switchable, it
      will be announced through the wp_tablet_pad_group.mode_switch event both
      whenever it is switched, and after wp_tablet_pad.enter.

      The current mode logically applies to all elements in the pad group,
      although it is at clients' discretion whether to actually perform different
      actions, and/or issue the respective .set_feedback requests to notify the
      compositor. See the wp_tablet_pad_group.mode_switch event for more details.
    
*/
class zwp_tablet_pad_group_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_pad_group_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_pad_group_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_pad_group_v2_t() = default;
  zwp_tablet_pad_group_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_pad_group_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_pad_group_v2*() const;

  /** \brief destroy the pad object

	Destroy the wp_tablet_pad_group object. Objects created from this object
	are unaffected and should be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

  /** \brief buttons announced
      \param buttons buttons in this group

	Sent on wp_tablet_pad_group initialization to announce the available
	buttons in the group. Button indices start at 0, a button may only be
	in one group at a time.

	This event is first sent in the initial burst of events before the
	wp_tablet_pad_group.done event.

	Some buttons are reserved by the compositor. These buttons may not be
	assigned to any wp_tablet_pad_group. Compositors may broadcast this
	event in the case of changes to the mapping of these reserved buttons.
	If the compositor happens to reserve all buttons in a group, this event
	will be sent with an empty array.
      
  */
  void buttons(array_t const& buttons, bool post = true);

  /** \brief Minimum protocol version required for the \ref buttons function
  */
  static constexpr std::uint32_t buttons_since_version = 1;

  /** \brief ring announced

	Sent on wp_tablet_pad_group initialization to announce available rings.
	One event is sent for each ring available on this pad group.

	This event is sent in the initial burst of events before the
	wp_tablet_pad_group.done event.
      
  */
  void ring(bool post = true);

  /** \brief Minimum protocol version required for the \ref ring function
  */
  static constexpr std::uint32_t ring_since_version = 1;

  /** \brief strip announced

	Sent on wp_tablet_pad initialization to announce available strips.
	One event is sent for each strip available on this pad group.

	This event is sent in the initial burst of events before the
	wp_tablet_pad_group.done event.
      
  */
  void strip(bool post = true);

  /** \brief Minimum protocol version required for the \ref strip function
  */
  static constexpr std::uint32_t strip_since_version = 1;

  /** \brief mode-switch ability announced
      \param modes the number of modes

	Sent on wp_tablet_pad_group initialization to announce that the pad
	group may switch between modes. A client may use a mode to store a
	specific configuration for buttons, rings and strips and use the
	wl_tablet_pad_group.mode_switch event to toggle between these
	configurations. Mode indices start at 0.

	Switching modes is compositor-dependent. See the
	wp_tablet_pad_group.mode_switch event for more details.

	This event is sent in the initial burst of events before the
	wp_tablet_pad_group.done event. This event is only sent when more than
	more than one mode is available.
      
  */
  void modes(uint32_t modes, bool post = true);

  /** \brief Minimum protocol version required for the \ref modes function
  */
  static constexpr std::uint32_t modes_since_version = 1;

  /** \brief tablet group description events sequence complete

	This event is sent immediately to signal the end of the initial
	burst of descriptive events. A client may consider the static
	description of the tablet to be complete and finalize initialization
	of the tablet group.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief mode switch event
      \param time the time of the event with millisecond granularity
      \param serial 
      \param mode the new mode of the pad

	Notification that the mode was switched.

	A mode applies to all buttons, rings and strips in a group
	simultaneously, but a client is not required to assign different actions
	for each mode. For example, a client may have mode-specific button
	mappings but map the ring to vertical scrolling in all modes. Mode
	indices start at 0.

	Switching modes is compositor-dependent. The compositor may provide
	visual cues to the client about the mode, e.g. by toggling LEDs on
	the tablet device. Mode-switching may be software-controlled or
	controlled by one or more physical buttons. For example, on a Wacom
	Intuos Pro, the button inside the ring may be assigned to switch
	between modes.

	The compositor will also send this event after wp_tablet_pad.enter on
	each group in order to notify of the current mode. Groups that only
	feature one mode will use mode=0 when emitting this event.

	If a button action in the new mode differs from the action in the
	previous mode, the client should immediately issue a
	wp_tablet_pad.set_feedback request for each changed button.

	If a ring or strip action in the new mode differs from the action
	in the previous mode, the client should immediately issue a
	wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request
	for each changed ring or strip.
      
  */
  void mode_switch(uint32_t time, uint32_t serial, uint32_t mode, bool post = true);

  /** \brief Minimum protocol version required for the \ref mode_switch function
  */
  static constexpr std::uint32_t mode_switch_since_version = 1;

};

using global_zwp_tablet_pad_group_v2_t = global_t<zwp_tablet_pad_group_v2_t>;


/** \brief a set of buttons, rings and strips

      A pad device is a set of buttons, rings and strips
      usually physically present on the tablet device itself. Some
      exceptions exist where the pad device is physically detached, e.g. the
      Wacom ExpressKey Remote.

      Pad devices have no axes that control the cursor and are generally
      auxiliary devices to the tool devices used on the tablet surface.

      A pad device has a number of static characteristics, e.g. the number
      of rings. These capabilities are sent in an event sequence after the
      wp_tablet_seat.pad_added event before any actual events from this pad.
      This initial event sequence is terminated by a wp_tablet_pad.done
      event.

      All pad features (buttons, rings and strips) are logically divided into
      groups and all pads have at least one group. The available groups are
      notified through the wp_tablet_pad.group event; the compositor will
      emit one event per group before emitting wp_tablet_pad.done.

      Groups may have multiple modes. Modes allow clients to map multiple
      actions to a single pad feature. Only one mode can be active per group,
      although different groups may have different active modes.
    
*/
class zwp_tablet_pad_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(uint32_t, std::string, uint32_t)> set_feedback;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_tablet_pad_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_tablet_pad_v2_t>;
  friend class global_base_t;

public:
  zwp_tablet_pad_v2_t() = default;
  zwp_tablet_pad_v2_t(const client_t& client, uint32_t id, int version = 1);
  zwp_tablet_pad_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_tablet_pad_v2*() const;

  /** \brief set compositor feedback
      \param button button index
      \param description button description
      \param serial serial of the mode switch event

	Requests the compositor to use the provided feedback string
	associated with this button. This request should be issued immediately
	after a wp_tablet_pad_group.mode_switch event from the corresponding
	group is received, or whenever a button is mapped to a different
	action. See wp_tablet_pad_group.mode_switch for more details.

	Clients are encouraged to provide context-aware descriptions for
	the actions associated with each button, and compositors may use
	this information to offer visual feedback on the button layout
	(e.g. on-screen displays).

	Button indices start at 0. Setting the feedback string on a button
	that is reserved by the compositor (i.e. not belonging to any
	wp_tablet_pad_group) does not generate an error but the compositor
	is free to ignore the request.

	The provided string 'description' is a UTF-8 encoded string to be
	associated with this ring, and is considered user-visible; general
	internationalization rules apply.

	The serial argument will be that of the last
	wp_tablet_pad_group.mode_switch event received for the group of this
	button. Requests providing other serials than the most recent one will
	be ignored.
      
  */
  std::function<void(uint32_t, std::string, uint32_t)> &on_set_feedback();

  /** \brief destroy the pad object

	Destroy the wp_tablet_pad object. Objects created from this object
	are unaffected and should be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

  /** \brief group announced

	Sent on wp_tablet_pad initialization to announce available groups.
	One event is sent for each pad group available.

	This event is sent in the initial burst of events before the
	wp_tablet_pad.done event. At least one group will be announced.
      
  */
  void group(bool post = true);

  /** \brief Minimum protocol version required for the \ref group function
  */
  static constexpr std::uint32_t group_since_version = 1;

  /** \brief path to the device
      \param path path to local device

	A system-specific device path that indicates which device is behind
	this wp_tablet_pad. This information may be used to gather additional
	information about the device, e.g. through libwacom.

	The format of the path is unspecified, it may be a device node, a
	sysfs path, or some other identifier. It is up to the client to
	identify the string provided.

	This event is sent in the initial burst of events before the
	wp_tablet_pad.done event.
      
  */
  void path(std::string const& path, bool post = true);

  /** \brief Minimum protocol version required for the \ref path function
  */
  static constexpr std::uint32_t path_since_version = 1;

  /** \brief buttons announced
      \param buttons the number of buttons

	Sent on wp_tablet_pad initialization to announce the available
	buttons.

	This event is sent in the initial burst of events before the
	wp_tablet_pad.done event. This event is only sent when at least one
	button is available.
      
  */
  void buttons(uint32_t buttons, bool post = true);

  /** \brief Minimum protocol version required for the \ref buttons function
  */
  static constexpr std::uint32_t buttons_since_version = 1;

  /** \brief pad description event sequence complete

	This event signals the end of the initial burst of descriptive
	events. A client may consider the static description of the pad to
	be complete and finalize initialization of the pad.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief physical button state
      \param time the time of the event with millisecond granularity
      \param button the index of the button that changed state
      \param state 

	Sent whenever the physical state of a button changes.
      
  */
  void button(uint32_t time, uint32_t button, zwp_tablet_pad_v2_button_state const& state, bool post = true);

  /** \brief Minimum protocol version required for the \ref button function
  */
  static constexpr std::uint32_t button_since_version = 1;

  /** \brief enter event
      \param serial serial number of the enter event
      \param tablet the tablet the pad is attached to
      \param surface surface the pad is focused on

	Notification that this pad is focused on the specified surface.
      
  */
  void enter(uint32_t serial, zwp_tablet_v2_t const& tablet, surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref enter function
  */
  static constexpr std::uint32_t enter_since_version = 1;

  /** \brief enter event
      \param serial serial number of the leave event
      \param surface surface the pad is no longer focused on

	Notification that this pad is no longer focused on the specified
	surface.
      
  */
  void leave(uint32_t serial, surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref leave function
  */
  static constexpr std::uint32_t leave_since_version = 1;

  /** \brief pad removed event

	Sent when the pad has been removed from the system. When a tablet
	is removed its pad(s) will be removed too.

	When this event is received, the client must destroy all rings, strips
	and groups that were offered by this pad, and issue wp_tablet_pad.destroy
	the pad itself.
      
  */
  void removed(bool post = true);

  /** \brief Minimum protocol version required for the \ref removed function
  */
  static constexpr std::uint32_t removed_since_version = 1;

};

using global_zwp_tablet_pad_v2_t = global_t<zwp_tablet_pad_v2_t>;

/** \brief physical button state

	Describes the physical state of a button that caused the button
	event.
      
  */
enum class zwp_tablet_pad_v2_button_state : uint32_t
  {
  /** \brief the button is not pressed */
  released = 0,
  /** \brief the button is pressed */
  pressed = 1
};


/** \brief text input

      An object used for text input. Adds support for text input and input
      methods to applications. A text_input object is created from a
      wl_text_input_manager and corresponds typically to a text entry in an
      application.

      Requests are used to activate/deactivate the text_input object and set
      state information like surrounding and selected text or the content type.
      The information about entered text is sent to the text_input object via
      the pre-edit and commit events. Using this interface removes the need
      for applications to directly process hardware key events and compose text
      out of them.

      Text is generally UTF-8 encoded, indices and lengths are in bytes.

      Serials are used to synchronize the state between the text input and
      an input method. New serials are sent by the text input in the
      commit_state request and are used by the input method to indicate
      the known text input state in events like preedit_string, commit_string,
      and keysym. The text input can then ignore events from the input method
      which are based on an outdated state (for example after a reset).

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zwp_text_input_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(seat_t, surface_t)> activate;
    std::function<void(seat_t)> deactivate;
    std::function<void()> show_input_panel;
    std::function<void()> hide_input_panel;
    std::function<void()> reset;
    std::function<void(std::string, uint32_t, uint32_t)> set_surrounding_text;
    std::function<void(zwp_text_input_v1_content_hint, zwp_text_input_v1_content_purpose)> set_content_type;
    std::function<void(int32_t, int32_t, int32_t, int32_t)> set_cursor_rectangle;
    std::function<void(std::string)> set_preferred_language;
    std::function<void(uint32_t)> commit_state;
    std::function<void(uint32_t, uint32_t)> invoke_action;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_text_input_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_text_input_v1_t>;
  friend class global_base_t;

public:
  zwp_text_input_v1_t() = default;
  zwp_text_input_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_text_input_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_text_input_v1*() const;

  /** \brief request activation
      \param seat 
      \param surface 

	Requests the text_input object to be activated (typically when the
	text entry gets focus).

	The seat argument is a wl_seat which maintains the focus for this
	activation. The surface argument is a wl_surface assigned to the
	text_input object and tracked for focus lost. The enter event
	is emitted on successful activation.
      
  */
  std::function<void(seat_t, surface_t)> &on_activate();

  /** \brief request deactivation
      \param seat 

	Requests the text_input object to be deactivated (typically when the
	text entry lost focus). The seat argument is a wl_seat which was used
	for activation.
      
  */
  std::function<void(seat_t)> &on_deactivate();

  /** \brief show input panels

	Requests input panels (virtual keyboard) to show.
      
  */
  std::function<void()> &on_show_input_panel();

  /** \brief hide input panels

	Requests input panels (virtual keyboard) to hide.
      
  */
  std::function<void()> &on_hide_input_panel();

  /** \brief reset

	Should be called by an editor widget when the input state should be
	reset, for example after the text was changed outside of the normal
	input method flow.
      
  */
  std::function<void()> &on_reset();

  /** \brief sets the surrounding text
      \param text 
      \param cursor 
      \param anchor 

	Sets the plain surrounding text around the input position. Text is
	UTF-8 encoded. Cursor is the byte offset within the
	surrounding text. Anchor is the byte offset of the
	selection anchor within the surrounding text. If there is no selected
	text anchor, then it is the same as cursor.
      
  */
  std::function<void(std::string, uint32_t, uint32_t)> &on_set_surrounding_text();

  /** \brief set content purpose and hint
      \param hint 
      \param purpose 

	Sets the content purpose and content hint. While the purpose is the
	basic purpose of an input field, the hint flags allow to modify some
	of the behavior.

	When no content type is explicitly set, a normal content purpose with
	default hints (auto completion, auto correction, auto capitalization)
	should be assumed.
      
  */
  std::function<void(zwp_text_input_v1_content_hint, zwp_text_input_v1_content_purpose)> &on_set_content_type();

  /** \brief 
      \param x 
      \param y 
      \param width 
      \param height 

  */
  std::function<void(int32_t, int32_t, int32_t, int32_t)> &on_set_cursor_rectangle();

  /** \brief sets preferred language
      \param language 

	Sets a specific language. This allows for example a virtual keyboard to
	show a language specific layout. The "language" argument is an RFC-3066
	format language tag.

	It could be used for example in a word processor to indicate the
	language of the currently edited document or in an instant message
	application which tracks languages of contacts.
      
  */
  std::function<void(std::string)> &on_set_preferred_language();

  /** \brief 
      \param serial used to identify the known state

  */
  std::function<void(uint32_t)> &on_commit_state();

  /** \brief 
      \param button 
      \param index 

  */
  std::function<void(uint32_t, uint32_t)> &on_invoke_action();

  /** \brief enter event
      \param surface 

	Notify the text_input object when it received focus. Typically in
	response to an activate request.
      
  */
  void enter(surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref enter function
  */
  static constexpr std::uint32_t enter_since_version = 1;

  /** \brief leave event

	Notify the text_input object when it lost focus. Either in response
	to a deactivate request or when the assigned surface lost focus or was
	destroyed.
      
  */
  void leave(bool post = true);

  /** \brief Minimum protocol version required for the \ref leave function
  */
  static constexpr std::uint32_t leave_since_version = 1;

  /** \brief modifiers map
      \param map 

	Transfer an array of 0-terminated modifier names. The position in
	the array is the index of the modifier as used in the modifiers
	bitmask in the keysym event.
      
  */
  void modifiers_map(array_t const& map, bool post = true);

  /** \brief Minimum protocol version required for the \ref modifiers_map function
  */
  static constexpr std::uint32_t modifiers_map_since_version = 1;

  /** \brief state of the input panel
      \param state 

	Notify when the visibility state of the input panel changed.
      
  */
  void input_panel_state(uint32_t state, bool post = true);

  /** \brief Minimum protocol version required for the \ref input_panel_state function
  */
  static constexpr std::uint32_t input_panel_state_since_version = 1;

  /** \brief pre-edit
      \param serial serial of the latest known text input state
      \param text 
      \param commit 

	Notify when a new composing text (pre-edit) should be set around the
	current cursor position. Any previously set composing text should
	be removed.

	The commit text can be used to replace the preedit text on reset
	(for example on unfocus).

	The text input should also handle all preedit_style and preedit_cursor
	events occurring directly before preedit_string.
      
  */
  void preedit_string(uint32_t serial, std::string const& text, std::string const& commit, bool post = true);

  /** \brief Minimum protocol version required for the \ref preedit_string function
  */
  static constexpr std::uint32_t preedit_string_since_version = 1;

  /** \brief pre-edit styling
      \param index 
      \param length 
      \param style 

	Sets styling information on composing text. The style is applied for
	length bytes from index relative to the beginning of the composing
	text (as byte offset). Multiple styles can
	be applied to a composing text by sending multiple preedit_styling
	events.

	This event is handled as part of a following preedit_string event.
      
  */
  void preedit_styling(uint32_t index, uint32_t length, zwp_text_input_v1_preedit_style const& style, bool post = true);

  /** \brief Minimum protocol version required for the \ref preedit_styling function
  */
  static constexpr std::uint32_t preedit_styling_since_version = 1;

  /** \brief pre-edit cursor
      \param index 

	Sets the cursor position inside the composing text (as byte
	offset) relative to the start of the composing text. When index is a
	negative number no cursor is shown.

	This event is handled as part of a following preedit_string event.
      
  */
  void preedit_cursor(int32_t index, bool post = true);

  /** \brief Minimum protocol version required for the \ref preedit_cursor function
  */
  static constexpr std::uint32_t preedit_cursor_since_version = 1;

  /** \brief commit
      \param serial serial of the latest known text input state
      \param text 

	Notify when text should be inserted into the editor widget. The text to
	commit could be either just a single character after a key press or the
	result of some composing (pre-edit). It could also be an empty text
	when some text should be removed (see delete_surrounding_text) or when
	the input cursor should be moved (see cursor_position).

	Any previously set composing text should be removed.
      
  */
  void commit_string(uint32_t serial, std::string const& text, bool post = true);

  /** \brief Minimum protocol version required for the \ref commit_string function
  */
  static constexpr std::uint32_t commit_string_since_version = 1;

  /** \brief set cursor to new position
      \param index 
      \param anchor 

	Notify when the cursor or anchor position should be modified.

	This event should be handled as part of a following commit_string
	event.
      
  */
  void cursor_position(int32_t index, int32_t anchor, bool post = true);

  /** \brief Minimum protocol version required for the \ref cursor_position function
  */
  static constexpr std::uint32_t cursor_position_since_version = 1;

  /** \brief delete surrounding text
      \param index 
      \param length 

	Notify when the text around the current cursor position should be
	deleted.

	Index is relative to the current cursor (in bytes).
	Length is the length of deleted text (in bytes).

	This event should be handled as part of a following commit_string
	event.
      
  */
  void delete_surrounding_text(int32_t index, uint32_t length, bool post = true);

  /** \brief Minimum protocol version required for the \ref delete_surrounding_text function
  */
  static constexpr std::uint32_t delete_surrounding_text_since_version = 1;

  /** \brief keysym
      \param serial serial of the latest known text input state
      \param time 
      \param sym 
      \param state 
      \param modifiers 

	Notify when a key event was sent. Key events should not be used
	for normal text input operations, which should be done with
	commit_string, delete_surrounding_text, etc. The key event follows
	the wl_keyboard key event convention. Sym is an XKB keysym, state a
	wl_keyboard key_state. Modifiers are a mask for effective modifiers
	(where the modifier indices are set by the modifiers_map event)
      
  */
  void keysym(uint32_t serial, uint32_t time, uint32_t sym, keyboard_key_state const& state, uint32_t modifiers, bool post = true);

  /** \brief Minimum protocol version required for the \ref keysym function
  */
  static constexpr std::uint32_t keysym_since_version = 1;

  /** \brief language
      \param serial serial of the latest known text input state
      \param language 

	Sets the language of the input text. The "language" argument is an
	RFC-3066 format language tag.
      
  */
  void language(uint32_t serial, std::string const& language, bool post = true);

  /** \brief Minimum protocol version required for the \ref language function
  */
  static constexpr std::uint32_t language_since_version = 1;

  /** \brief text direction
      \param serial serial of the latest known text input state
      \param direction 

	Sets the text direction of input text.

	It is mainly needed for showing an input cursor on the correct side of
	the editor when there is no input done yet and making sure neutral
	direction text is laid out properly.
      
  */
  void text_direction(uint32_t serial, zwp_text_input_v1_text_direction const& direction, bool post = true);

  /** \brief Minimum protocol version required for the \ref text_direction function
  */
  static constexpr std::uint32_t text_direction_since_version = 1;

};

using global_zwp_text_input_v1_t = global_t<zwp_text_input_v1_t>;

/** \brief content hint

	Content hint is a bitmask to allow to modify the behavior of the text
	input.
      
  */
struct zwp_text_input_v1_content_hint : public wayland::detail::bitfield<10, 23>
{
  zwp_text_input_v1_content_hint(const wayland::detail::bitfield<10, 23> &b)
    : wayland::detail::bitfield<10, 23>(b) {}
  zwp_text_input_v1_content_hint(const uint32_t value)
    : wayland::detail::bitfield<10, 23>(value) {}
  /** \brief no special behaviour */
  static const wayland::detail::bitfield<10, 23> none;
  /** \brief auto completion, correction and capitalization */
  static const wayland::detail::bitfield<10, 23> _default;
  /** \brief hidden and sensitive text */
  static const wayland::detail::bitfield<10, 23> password;
  /** \brief suggest word completions */
  static const wayland::detail::bitfield<10, 23> auto_completion;
  /** \brief suggest word corrections */
  static const wayland::detail::bitfield<10, 23> auto_correction;
  /** \brief switch to uppercase letters at the start of a sentence */
  static const wayland::detail::bitfield<10, 23> auto_capitalization;
  /** \brief prefer lowercase letters */
  static const wayland::detail::bitfield<10, 23> lowercase;
  /** \brief prefer uppercase letters */
  static const wayland::detail::bitfield<10, 23> uppercase;
  /** \brief prefer casing for titles and headings (can be language dependent) */
  static const wayland::detail::bitfield<10, 23> titlecase;
  /** \brief characters should be hidden */
  static const wayland::detail::bitfield<10, 23> hidden_text;
  /** \brief typed text should not be stored */
  static const wayland::detail::bitfield<10, 23> sensitive_data;
  /** \brief just latin characters should be entered */
  static const wayland::detail::bitfield<10, 23> latin;
  /** \brief the text input is multiline */
  static const wayland::detail::bitfield<10, 23> multiline;
};

/** \brief content purpose

	The content purpose allows to specify the primary purpose of a text
	input.

	This allows an input method to show special purpose input panels with
	extra characters or to disallow some characters.
      
  */
enum class zwp_text_input_v1_content_purpose : uint32_t
  {
  /** \brief default input, allowing all characters */
  normal = 0,
  /** \brief allow only alphabetic characters */
  alpha = 1,
  /** \brief allow only digits */
  digits = 2,
  /** \brief input a number (including decimal separator and sign) */
  number = 3,
  /** \brief input a phone number */
  phone = 4,
  /** \brief input an URL */
  url = 5,
  /** \brief input an email address */
  email = 6,
  /** \brief input a name of a person */
  name = 7,
  /** \brief input a password (combine with password or sensitive_data hint) */
  password = 8,
  /** \brief input a date */
  date = 9,
  /** \brief input a time */
  time = 10,
  /** \brief input a date and time */
  datetime = 11,
  /** \brief input for a terminal */
  terminal = 12
};

/** \brief 

  */
enum class zwp_text_input_v1_preedit_style : uint32_t
  {
  /** \brief default style for composing text */
  _default = 0,
  /** \brief style should be the same as in non-composing text */
  none = 1,
  active = 2,
  inactive = 3,
  highlight = 4,
  underline = 5,
  selection = 6,
  incorrect = 7
};

/** \brief 

  */
enum class zwp_text_input_v1_text_direction : uint32_t
  {
  /** \brief automatic text direction based on text and language */
  _auto = 0,
  /** \brief left-to-right */
  ltr = 1,
  /** \brief right-to-left */
  rtl = 2
};


/** \brief text input manager

      A factory for text_input objects. This object is a global singleton.
    
*/
class zwp_text_input_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(zwp_text_input_v1_t)> create_text_input;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_text_input_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_text_input_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_text_input_manager_v1_t() = default;
  zwp_text_input_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_text_input_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_text_input_manager_v1*() const;

  /** \brief create text input
      \param id 

	Creates a new text_input object.
      
  */
  std::function<void(zwp_text_input_v1_t)> &on_create_text_input();

};

using global_zwp_text_input_manager_v1_t = global_t<zwp_text_input_manager_v1_t>;


/** \brief text input

      The zwp_text_input_v3 interface represents text input and input methods
      associated with a seat. It provides enter/leave events to follow the
      text input focus for a seat.

      Requests are used to enable/disable the text-input object and set
      state information like surrounding and selected text or the content type.
      The information about the entered text is sent to the text-input object
      via the preedit_string and commit_string events.

      Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices
      must not point to middle bytes inside a code point: they must either
      point to the first byte of a code point or to the end of the buffer.
      Lengths must be measured between two valid indices.

      Focus moving throughout surfaces will result in the emission of
      zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused
      surface must commit zwp_text_input_v3.enable and
      zwp_text_input_v3.disable requests as the keyboard focus moves across
      editable and non-editable elements of the UI. Those two requests are not
      expected to be paired with each other, the compositor must be able to
      handle consecutive series of the same request.

      State is sent by the state requests (set_surrounding_text,
      set_content_type and set_cursor_rectangle) and a commit request. After an
      enter event or disable request all state information is invalidated and
      needs to be resent by the client.
    
*/
class zwp_text_input_v3_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void()> enable;
    std::function<void()> disable;
    std::function<void(std::string, int32_t, int32_t)> set_surrounding_text;
    std::function<void(zwp_text_input_v3_change_cause)> set_text_change_cause;
    std::function<void(zwp_text_input_v3_content_hint, zwp_text_input_v3_content_purpose)> set_content_type;
    std::function<void(int32_t, int32_t, int32_t, int32_t)> set_cursor_rectangle;
    std::function<void()> commit;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_text_input_v3_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_text_input_v3_t>;
  friend class global_base_t;

public:
  zwp_text_input_v3_t() = default;
  zwp_text_input_v3_t(const client_t& client, uint32_t id, int version = 1);
  zwp_text_input_v3_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_text_input_v3*() const;

  /** \brief Destroy the wp_text_input

        Destroy the wp_text_input object. Also disables all surfaces enabled
        through this wp_text_input object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief Request text input to be enabled

        Requests text input on the surface previously obtained from the enter
        event.

        This request must be issued every time the active text input changes
        to a new one, including within the current surface. Use
        zwp_text_input_v3.disable when there is no longer any input focus on
        the current surface.

        Clients must not enable more than one text input on the single seat
        and should disable the current text input before enabling the new one.
        At most one instance of text input may be in enabled state per instance,
        Requests to enable the another text input when some text input is active
        must be ignored by compositor.

        This request resets all state associated with previous enable, disable,
        set_surrounding_text, set_text_change_cause, set_content_type, and
        set_cursor_rectangle requests, as well as the state associated with
        preedit_string, commit_string, and delete_surrounding_text events.

        The set_surrounding_text, set_content_type and set_cursor_rectangle
        requests must follow if the text input supports the necessary
        functionality.

        State set with this request is double-buffered. It will get applied on
        the next zwp_text_input_v3.commit request, and stay valid until the
        next committed enable or disable request.

        The changes must be applied by the compositor after issuing a
        zwp_text_input_v3.commit request.
      
  */
  std::function<void()> &on_enable();

  /** \brief Disable text input on a surface

        Explicitly disable text input on the current surface (typically when
        there is no focus on any text entry inside the surface).

        State set with this request is double-buffered. It will get applied on
        the next zwp_text_input_v3.commit request.
      
  */
  std::function<void()> &on_disable();

  /** \brief sets the surrounding text
      \param text 
      \param cursor 
      \param anchor 

        Sets the surrounding plain text around the input, excluding the preedit
        text.

        The client should notify the compositor of any changes in any of the
        values carried with this request, including changes caused by handling
        incoming text-input events as well as changes caused by other
        mechanisms like keyboard typing.

        If the client is unaware of the text around the cursor, it should not
        issue this request, to signify lack of support to the compositor.

        Text is UTF-8 encoded, and should include the cursor position, the
        complete selection and additional characters before and after them.
        There is a maximum length of wayland messages, so text can not be
        longer than 4000 bytes.

        Cursor is the byte offset of the cursor within text buffer.

        Anchor is the byte offset of the selection anchor within text buffer.
        If there is no selected text, anchor is the same as cursor.

        If any preedit text is present, it is replaced with a cursor for the
        purpose of this event.

        Values set with this request are double-buffered. They will get applied
        on the next zwp_text_input_v3.commit request, and stay valid until the
        next committed enable or disable request.

        The initial state for affected fields is empty, meaning that the text
        input does not support sending surrounding text. If the empty values
        get applied, subsequent attempts to change them may have no effect.
      
  */
  std::function<void(std::string, int32_t, int32_t)> &on_set_surrounding_text();

  /** \brief indicates the cause of surrounding text change
      \param cause 

        Tells the compositor why the text surrounding the cursor changed.

        Whenever the client detects an external change in text, cursor, or
        anchor posision, it must issue this request to the compositor. This
        request is intended to give the input method a chance to update the
        preedit text in an appropriate way, e.g. by removing it when the user
        starts typing with a keyboard.

        cause describes the source of the change.

        The value set with this request is double-buffered. It must be applied
        and reset to initial at the next zwp_text_input_v3.commit request.

        The initial value of cause is input_method.
      
  */
  std::function<void(zwp_text_input_v3_change_cause)> &on_set_text_change_cause();

  /** \brief set content purpose and hint
      \param hint 
      \param purpose 

        Sets the content purpose and content hint. While the purpose is the
        basic purpose of an input field, the hint flags allow to modify some of
        the behavior.

        Values set with this request are double-buffered. They will get applied
        on the next zwp_text_input_v3.commit request.
        Subsequent attempts to update them may have no effect. The values
        remain valid until the next committed enable or disable request.

        The initial value for hint is none, and the initial value for purpose
        is normal.
      
  */
  std::function<void(zwp_text_input_v3_content_hint, zwp_text_input_v3_content_purpose)> &on_set_content_type();

  /** \brief set cursor position
      \param x 
      \param y 
      \param width 
      \param height 

        Marks an area around the cursor as a x, y, width, height rectangle in
        surface local coordinates.

        Allows the compositor to put a window with word suggestions near the
        cursor, without obstructing the text being input.

        If the client is unaware of the position of edited text, it should not
        issue this request, to signify lack of support to the compositor.

        Values set with this request are double-buffered. They will get applied
        on the next zwp_text_input_v3.commit request, and stay valid until the
        next committed enable or disable request.

        The initial values describing a cursor rectangle are empty. That means
        the text input does not support describing the cursor area. If the
        empty values get applied, subsequent attempts to change them may have
        no effect.
      
  */
  std::function<void(int32_t, int32_t, int32_t, int32_t)> &on_set_cursor_rectangle();

  /** \brief commit state

        Atomically applies state changes recently sent to the compositor.

        The commit request establishes and updates the state of the client, and
        must be issued after any changes to apply them.

        Text input state (enabled status, content purpose, content hint,
        surrounding text and change cause, cursor rectangle) is conceptually
        double-buffered within the context of a text input, i.e. between a
        committed enable request and the following committed enable or disable
        request.

        Protocol requests modify the pending state, as opposed to the current
        state in use by the input method. A commit request atomically applies
        all pending state, replacing the current state. After commit, the new
        pending state is as documented for each related request.

        Requests are applied in the order of arrival.

        Neither current nor pending state are modified unless noted otherwise.

        The compositor must count the number of commit requests coming from
        each zwp_text_input_v3 object and use the count as the serial in done
        events.
      
  */
  std::function<void()> &on_commit();

  /** \brief enter event
      \param surface 

        Notification that this seat's text-input focus is on a certain surface.

        If client has created multiple text input objects, compositor must send
        this event to all of them.

        When the seat has the keyboard capability the text-input focus follows
        the keyboard focus. This event sets the current surface for the
        text-input object.
      
  */
  void enter(surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref enter function
  */
  static constexpr std::uint32_t enter_since_version = 1;

  /** \brief leave event
      \param surface 

        Notification that this seat's text-input focus is no longer on a
        certain surface. The client should reset any preedit string previously
        set.

        The leave notification clears the current surface. It is sent before
        the enter notification for the new focus. After leave event, compositor
        must ignore requests from any text input instances until next enter
        event.

        When the seat has the keyboard capability the text-input focus follows
        the keyboard focus.
      
  */
  void leave(surface_t const& surface, bool post = true);

  /** \brief Minimum protocol version required for the \ref leave function
  */
  static constexpr std::uint32_t leave_since_version = 1;

  /** \brief pre-edit
      \param text 
      \param cursor_begin 
      \param cursor_end 

        Notify when a new composing text (pre-edit) should be set at the
        current cursor position. Any previously set composing text must be
        removed. Any previously existing selected text must be removed.

        The argument text contains the pre-edit string buffer.

        The parameters cursor_begin and cursor_end are counted in bytes
        relative to the beginning of the submitted text buffer. Cursor should
        be hidden when both are equal to -1.

        They could be represented by the client as a line if both values are
        the same, or as a text highlight otherwise.

        Values set with this event are double-buffered. They must be applied
        and reset to initial on the next zwp_text_input_v3.done event.

        The initial value of text is an empty string, and cursor_begin,
        cursor_end and cursor_hidden are all 0.
      
  */
  void preedit_string(std::string const& text, int32_t cursor_begin, int32_t cursor_end, bool post = true);

  /** \brief Minimum protocol version required for the \ref preedit_string function
  */
  static constexpr std::uint32_t preedit_string_since_version = 1;

  /** \brief text commit
      \param text 

        Notify when text should be inserted into the editor widget. The text to
        commit could be either just a single character after a key press or the
        result of some composing (pre-edit).

        Values set with this event are double-buffered. They must be applied
        and reset to initial on the next zwp_text_input_v3.done event.

        The initial value of text is an empty string.
      
  */
  void commit_string(std::string const& text, bool post = true);

  /** \brief Minimum protocol version required for the \ref commit_string function
  */
  static constexpr std::uint32_t commit_string_since_version = 1;

  /** \brief delete surrounding text
      \param before_length length of text before current cursor position
      \param after_length length of text after current cursor position

        Notify when the text around the current cursor position should be
        deleted.

        Before_length and after_length are the number of bytes before and after
        the current cursor index (excluding the selection) to delete.

        If a preedit text is present, in effect before_length is counted from
        the beginning of it, and after_length from its end (see done event
        sequence).

        Values set with this event are double-buffered. They must be applied
        and reset to initial on the next zwp_text_input_v3.done event.

        The initial values of both before_length and after_length are 0.
      
  */
  void delete_surrounding_text(uint32_t before_length, uint32_t after_length, bool post = true);

  /** \brief Minimum protocol version required for the \ref delete_surrounding_text function
  */
  static constexpr std::uint32_t delete_surrounding_text_since_version = 1;

  /** \brief apply changes
      \param serial 

        Instruct the application to apply changes to state requested by the
        preedit_string, commit_string and delete_surrounding_text events. The
        state relating to these events is double-buffered, and each one
        modifies the pending state. This event replaces the current state with
        the pending state.

        The application must proceed by evaluating the changes in the following
        order:

        1. Replace existing preedit string with the cursor.
        2. Delete requested surrounding text.
        3. Insert commit string with the cursor at its end.
        4. Calculate surrounding text to send.
        5. Insert new preedit text in cursor position.
        6. Place cursor inside preedit text.

        The serial number reflects the last state of the zwp_text_input_v3
        object known to the compositor. The value of the serial argument must
        be equal to the number of commit requests already issued on that object.
        When the client receives a done event with a serial different than the
        number of past commit requests, it must proceed as normal, except it
        should not change the current state of the zwp_text_input_v3 object.
      
  */
  void done(uint32_t serial, bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

};

using global_zwp_text_input_v3_t = global_t<zwp_text_input_v3_t>;

/** \brief text change reason

        Reason for the change of surrounding text or cursor posision.
      
  */
enum class zwp_text_input_v3_change_cause : uint32_t
  {
  /** \brief input method caused the change */
  input_method = 0,
  /** \brief something else than the input method caused the change */
  other = 1
};

/** \brief content hint

        Content hint is a bitmask to allow to modify the behavior of the text
        input.
      
  */
struct zwp_text_input_v3_content_hint : public wayland::detail::bitfield<10, 28>
{
  zwp_text_input_v3_content_hint(const wayland::detail::bitfield<10, 28> &b)
    : wayland::detail::bitfield<10, 28>(b) {}
  zwp_text_input_v3_content_hint(const uint32_t value)
    : wayland::detail::bitfield<10, 28>(value) {}
  /** \brief no special behavior */
  static const wayland::detail::bitfield<10, 28> none;
  /** \brief suggest word completions */
  static const wayland::detail::bitfield<10, 28> completion;
  /** \brief suggest word corrections */
  static const wayland::detail::bitfield<10, 28> spellcheck;
  /** \brief switch to uppercase letters at the start of a sentence */
  static const wayland::detail::bitfield<10, 28> auto_capitalization;
  /** \brief prefer lowercase letters */
  static const wayland::detail::bitfield<10, 28> lowercase;
  /** \brief prefer uppercase letters */
  static const wayland::detail::bitfield<10, 28> uppercase;
  /** \brief prefer casing for titles and headings (can be language dependent) */
  static const wayland::detail::bitfield<10, 28> titlecase;
  /** \brief characters should be hidden */
  static const wayland::detail::bitfield<10, 28> hidden_text;
  /** \brief typed text should not be stored */
  static const wayland::detail::bitfield<10, 28> sensitive_data;
  /** \brief just Latin characters should be entered */
  static const wayland::detail::bitfield<10, 28> latin;
  /** \brief the text input is multiline */
  static const wayland::detail::bitfield<10, 28> multiline;
};

/** \brief content purpose

        The content purpose allows to specify the primary purpose of a text
        input.

        This allows an input method to show special purpose input panels with
        extra characters or to disallow some characters.
      
  */
enum class zwp_text_input_v3_content_purpose : uint32_t
  {
  /** \brief default input, allowing all characters */
  normal = 0,
  /** \brief allow only alphabetic characters */
  alpha = 1,
  /** \brief allow only digits */
  digits = 2,
  /** \brief input a number (including decimal separator and sign) */
  number = 3,
  /** \brief input a phone number */
  phone = 4,
  /** \brief input an URL */
  url = 5,
  /** \brief input an email address */
  email = 6,
  /** \brief input a name of a person */
  name = 7,
  /** \brief input a password (combine with sensitive_data hint) */
  password = 8,
  /** \brief input is a numeric password (combine with sensitive_data hint) */
  pin = 9,
  /** \brief input a date */
  date = 10,
  /** \brief input a time */
  time = 11,
  /** \brief input a date and time */
  datetime = 12,
  /** \brief input for a terminal */
  terminal = 13
};


/** \brief text input manager

      A factory for text-input objects. This object is a global singleton.
    
*/
class zwp_text_input_manager_v3_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_text_input_v3_t, seat_t)> get_text_input;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_text_input_manager_v3_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_text_input_manager_v3_t>;
  friend class global_base_t;

public:
  zwp_text_input_manager_v3_t() = default;
  zwp_text_input_manager_v3_t(const client_t& client, uint32_t id, int version = 1);
  zwp_text_input_manager_v3_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_text_input_manager_v3*() const;

  /** \brief Destroy the wp_text_input_manager

        Destroy the wp_text_input_manager object.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create a new text input object
      \param id 
      \param seat 

        Creates a new text-input object for a given seat.
      
  */
  std::function<void(zwp_text_input_v3_t, seat_t)> &on_get_text_input();

};

using global_zwp_text_input_manager_v3_t = global_t<zwp_text_input_manager_v3_t>;


/** \brief interface for activating surfaces

      A global interface used for informing the compositor about applications
      being activated or started, or for applications to request to be
      activated.
    
*/
class xdg_activation_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(xdg_activation_token_v1_t)> get_activation_token;
    std::function<void(std::string, surface_t)> activate;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::xdg_activation_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<xdg_activation_v1_t>;
  friend class global_base_t;

public:
  xdg_activation_v1_t() = default;
  xdg_activation_v1_t(const client_t& client, uint32_t id, int version = 1);
  xdg_activation_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator xdg_activation_v1*() const;

  /** \brief destroy the xdg_activation object

        Notify the compositor that the xdg_activation object will no longer be
        used.

        The child objects created via this interface are unaffected and should
        be destroyed separately.
      
  */
  std::function<void()> &on_destroy();

  /** \brief requests a token
      \param id 

        Creates an xdg_activation_token_v1 object that will provide
        the initiating client with a unique token for this activation. This
        token should be offered to the clients to be activated.
      
  */
  std::function<void(xdg_activation_token_v1_t)> &on_get_activation_token();

  /** \brief notify new interaction being available
      \param token the activation token of the initiating client
      \param surface the wl_surface to activate

        Requests surface activation. It's up to the compositor to display
        this information as desired, for example by placing the surface above
        the rest.

        The compositor may know who requested this by checking the activation
        token and might decide not to follow through with the activation if it's
        considered unwanted.

        Compositors can ignore unknown presentation tokens when an invalid
        token is passed.
      
  */
  std::function<void(std::string, surface_t)> &on_activate();

};

using global_xdg_activation_v1_t = global_t<xdg_activation_v1_t>;


/** \brief an exported activation handle

      An object for setting up a token and receiving a token handle that can
      be passed as an activation token to another client.

      The object is created using the xdg_activation_v1.get_activation_token
      request. This object should then be populated with the app_id, surface
      and serial information and committed. The compositor shall then issue a
      done event with the token. In case the request's parameters are invalid,
      the compositor will provide an invalid token.
    
*/
class xdg_activation_token_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void(uint32_t, seat_t)> set_serial;
    std::function<void(std::string)> set_app_id;
    std::function<void(surface_t)> set_surface;
    std::function<void()> commit;
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::xdg_activation_token_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<xdg_activation_token_v1_t>;
  friend class global_base_t;

public:
  xdg_activation_token_v1_t() = default;
  xdg_activation_token_v1_t(const client_t& client, uint32_t id, int version = 1);
  xdg_activation_token_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator xdg_activation_token_v1*() const;

  /** \brief specifies the seat and serial of the activating event
      \param serial the serial of the event that triggered the activation
      \param seat the wl_seat of the event

        Provides information about the seat and serial event that requested the
        token.

        Must be sent before commit. This information is optional.
      
  */
  std::function<void(uint32_t, seat_t)> &on_set_serial();

  /** \brief specifies the application being activated
      \param app_id the application id of the client being activated.

        The requesting client can specify an app_id to associate the token
        being created with it.

        Must be sent before commit. This information is optional.
      
  */
  std::function<void(std::string)> &on_set_app_id();

  /** \brief specifies the application being activated
      \param surface the requesting surface

        The requesting client can specify a surface to associate the token
        being created with it.

        Must be triggered before commit. This information is optional.
      
  */
  std::function<void(surface_t)> &on_set_surface();

  /** \brief issues the token request

        Requests an activation token based on the different parameters that
        have been offered through set_serial, set_surface and set_app_id.
      
  */
  std::function<void()> &on_commit();

  /** \brief destroy the xdg_activation_token_v1 object

        Notify the compositor that the xdg_activation_token_v1 object will no
        longer be used.
      
  */
  std::function<void()> &on_destroy();

  /** \brief the exported activation token
      \param token the exported activation token

        The 'done' event contains the unique token of this activation request
        and notifies that the provider is done.

        Applications will typically receive the token through the
        XDG_ACTIVATION_TOKEN environment variable as set by its launcher, and
        should unset the environment variable right after this request, in
        order to avoid propagating it to child processes.

        Applications implementing the D-Bus interface org.freedesktop.Application
        should get their token under XDG_ACTIVATION_TOKEN on their platform_data.

        Presentation tokens may be transferred across clients through means not
        described in this protocol.
      
  */
  void done(std::string const& token, bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief Post error: The token has already been used previously
  */
  void post_already_used(std::string const& msg);

};

using global_xdg_activation_token_v1_t = global_t<xdg_activation_token_v1_t>;

/** \brief 

  */
enum class xdg_activation_token_v1_error : uint32_t
  {
  /** \brief The token has already been used previously */
  already_used = 0
};


/** \brief window decoration manager

      This interface allows a compositor to announce support for server-side
      decorations.

      A window decoration is a set of window controls as deemed appropriate by
      the party managing them, such as user interface components used to move,
      resize and change a window's state.

      A client can use this protocol to request being decorated by a supporting
      compositor.

      If compositor and client do not negotiate the use of a server-side
      decoration using this protocol, clients continue to self-decorate as they
      see fit.

      Warning! The protocol described in this file is experimental and
      backward incompatible changes may be made. Backward compatible changes
      may be added together with the corresponding interface version bump.
      Backward incompatible changes are done by bumping the version number in
      the protocol and interface names and resetting the interface version.
      Once the protocol is to be declared stable, the 'z' prefix and the
      version number in the protocol and interface names are removed and the
      interface version number is reset.
    
*/
class zxdg_decoration_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_toplevel_decoration_v1_t, xdg_toplevel_t)> get_toplevel_decoration;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_decoration_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_decoration_manager_v1_t>;
  friend class global_base_t;

public:
  zxdg_decoration_manager_v1_t() = default;
  zxdg_decoration_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_decoration_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_decoration_manager_v1*() const;

  /** \brief destroy the decoration manager object

        Destroy the decoration manager. This doesn't destroy objects created
        with the manager.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create a new toplevel decoration object
      \param id 
      \param toplevel 

        Create a new decoration object associated with the given toplevel.

        Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
        buffer attached or committed is a client error, and any attempts by a
        client to attach or manipulate a buffer prior to the first
        xdg_toplevel_decoration.configure event must also be treated as
        errors.
      
  */
  std::function<void(zxdg_toplevel_decoration_v1_t, xdg_toplevel_t)> &on_get_toplevel_decoration();

};

using global_zxdg_decoration_manager_v1_t = global_t<zxdg_decoration_manager_v1_t>;


/** \brief decoration object for a toplevel surface

      The decoration object allows the compositor to toggle server-side window
      decorations for a toplevel surface. The client can request to switch to
      another mode.

      The xdg_toplevel_decoration object must be destroyed before its
      xdg_toplevel.
    
*/
class zxdg_toplevel_decoration_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_toplevel_decoration_v1_mode)> set_mode;
    std::function<void()> unset_mode;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_toplevel_decoration_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_toplevel_decoration_v1_t>;
  friend class global_base_t;

public:
  zxdg_toplevel_decoration_v1_t() = default;
  zxdg_toplevel_decoration_v1_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_toplevel_decoration_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_toplevel_decoration_v1*() const;

  /** \brief destroy the decoration object

        Switch back to a mode without any server-side decorations at the next
        commit.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set the decoration mode
      \param mode the decoration mode

        Set the toplevel surface decoration mode. This informs the compositor
        that the client prefers the provided decoration mode.

        After requesting a decoration mode, the compositor will respond by
        emitting an xdg_surface.configure event. The client should then update
        its content, drawing it without decorations if the received mode is
        server-side decorations. The client must also acknowledge the configure
        when committing the new content (see xdg_surface.ack_configure).

        The compositor can decide not to use the client's mode and enforce a
        different mode instead.

        Clients whose decoration mode depend on the xdg_toplevel state may send
        a set_mode request in response to an xdg_surface.configure event and wait
        for the next xdg_surface.configure event to prevent unwanted state.
        Such clients are responsible for preventing configure loops and must
        make sure not to send multiple successive set_mode requests with the
        same decoration mode.
      
  */
  std::function<void(zxdg_toplevel_decoration_v1_mode)> &on_set_mode();

  /** \brief unset the decoration mode

        Unset the toplevel surface decoration mode. This informs the compositor
        that the client doesn't prefer a particular decoration mode.

        This request has the same semantics as set_mode.
      
  */
  std::function<void()> &on_unset_mode();

  /** \brief suggest a surface change
      \param mode the decoration mode

        The configure event asks the client to change its decoration mode. The
        configured state should not be applied immediately. Clients must send an
        ack_configure in response to this event. See xdg_surface.configure and
        xdg_surface.ack_configure for details.

        A configure event can be sent at any time. The specified mode must be
        obeyed by the client.
      
  */
  void configure(zxdg_toplevel_decoration_v1_mode const& mode, bool post = true);

  /** \brief Minimum protocol version required for the \ref configure function
  */
  static constexpr std::uint32_t configure_since_version = 1;

  /** \brief Post error: xdg_toplevel has a buffer attached before configure
  */
  void post_unconfigured_buffer(std::string const& msg);

  /** \brief Post error: xdg_toplevel already has a decoration object
  */
  void post_already_constructed(std::string const& msg);

  /** \brief Post error: xdg_toplevel destroyed before the decoration object
  */
  void post_orphaned(std::string const& msg);

};

using global_zxdg_toplevel_decoration_v1_t = global_t<zxdg_toplevel_decoration_v1_t>;

/** \brief 

  */
enum class zxdg_toplevel_decoration_v1_error : uint32_t
  {
  /** \brief xdg_toplevel has a buffer attached before configure */
  unconfigured_buffer = 0,
  /** \brief xdg_toplevel already has a decoration object */
  already_constructed = 1,
  /** \brief xdg_toplevel destroyed before the decoration object */
  orphaned = 2
};

/** \brief window decoration modes

        These values describe window decoration modes.
      
  */
enum class zxdg_toplevel_decoration_v1_mode : uint32_t
  {
  /** \brief no server-side window decoration */
  client_side = 1,
  /** \brief server-side window decoration */
  server_side = 2
};


/** \brief interface for exporting surfaces

      A global interface used for exporting surfaces that can later be imported
      using xdg_importer.
    
*/
class zxdg_exporter_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_exported_v1_t, surface_t)> _export;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_exporter_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_exporter_v1_t>;
  friend class global_base_t;

public:
  zxdg_exporter_v1_t() = default;
  zxdg_exporter_v1_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_exporter_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_exporter_v1*() const;

  /** \brief destroy the xdg_exporter object

	Notify the compositor that the xdg_exporter object will no longer be
	used.
      
  */
  std::function<void()> &on_destroy();

  /** \brief export a surface
      \param id the new xdg_exported object
      \param surface the surface to export

	The export request exports the passed surface so that it can later be
	imported via xdg_importer. When called, a new xdg_exported object will
	be created and xdg_exported.handle will be sent immediately. See the
	corresponding interface and event for details.

	A surface may be exported multiple times, and each exported handle may
	be used to create an xdg_imported multiple times. Only xdg_surface
	surfaces may be exported.
      
  */
  std::function<void(zxdg_exported_v1_t, surface_t)> &on_export();

};

using global_zxdg_exporter_v1_t = global_t<zxdg_exporter_v1_t>;


/** \brief interface for importing surfaces

      A global interface used for importing surfaces exported by xdg_exporter.
      With this interface, a client can create a reference to a surface of
      another client.
    
*/
class zxdg_importer_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_imported_v1_t, std::string)> import;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_importer_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_importer_v1_t>;
  friend class global_base_t;

public:
  zxdg_importer_v1_t() = default;
  zxdg_importer_v1_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_importer_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_importer_v1*() const;

  /** \brief destroy the xdg_importer object

	Notify the compositor that the xdg_importer object will no longer be
	used.
      
  */
  std::function<void()> &on_destroy();

  /** \brief import a surface
      \param id the new xdg_imported object
      \param handle the exported surface handle

	The import request imports a surface from any client given a handle
	retrieved by exporting said surface using xdg_exporter.export. When
	called, a new xdg_imported object will be created. This new object
	represents the imported surface, and the importing client can
	manipulate its relationship using it. See xdg_imported for details.
      
  */
  std::function<void(zxdg_imported_v1_t, std::string)> &on_import();

};

using global_zxdg_importer_v1_t = global_t<zxdg_importer_v1_t>;


/** \brief an exported surface handle

      An xdg_exported object represents an exported reference to a surface. The
      exported surface may be referenced as long as the xdg_exported object not
      destroyed. Destroying the xdg_exported invalidates any relationship the
      importer may have established using xdg_imported.
    
*/
class zxdg_exported_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_exported_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_exported_v1_t>;
  friend class global_base_t;

public:
  zxdg_exported_v1_t() = default;
  zxdg_exported_v1_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_exported_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_exported_v1*() const;

  /** \brief unexport the exported surface

	Revoke the previously exported surface. This invalidates any
	relationship the importer may have set up using the xdg_imported created
	given the handle sent via xdg_exported.handle.
      
  */
  std::function<void()> &on_destroy();

  /** \brief the exported surface handle
      \param handle the exported surface handle

	The handle event contains the unique handle of this exported surface
	reference. It may be shared with any client, which then can use it to
	import the surface by calling xdg_importer.import. A handle may be
	used to import the surface multiple times.
      
  */
  void handle(std::string const& handle, bool post = true);

  /** \brief Minimum protocol version required for the \ref handle function
  */
  static constexpr std::uint32_t handle_since_version = 1;

};

using global_zxdg_exported_v1_t = global_t<zxdg_exported_v1_t>;


/** \brief an imported surface handle

      An xdg_imported object represents an imported reference to surface exported
      by some client. A client can use this interface to manipulate
      relationships between its own surfaces and the imported surface.
    
*/
class zxdg_imported_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(surface_t)> set_parent_of;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_imported_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_imported_v1_t>;
  friend class global_base_t;

public:
  zxdg_imported_v1_t() = default;
  zxdg_imported_v1_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_imported_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_imported_v1*() const;

  /** \brief destroy the xdg_imported object

	Notify the compositor that it will no longer use the xdg_imported
	object. Any relationship that may have been set up will at this point
	be invalidated.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set as the parent of some surface
      \param surface the child surface

	Set the imported surface as the parent of some surface of the client.
	The passed surface must be a toplevel xdg_surface. Calling this function
	sets up a surface to surface relation with the same stacking and positioning
	semantics as xdg_surface.set_parent.
      
  */
  std::function<void(surface_t)> &on_set_parent_of();

  /** \brief the imported surface handle has been destroyed

	The imported surface handle has been destroyed and any relationship set
	up has been invalidated. This may happen for various reasons, for
	example if the exported surface or the exported surface handle has been
	destroyed, if the handle used for importing was invalid.
      
  */
  void destroyed(bool post = true);

  /** \brief Minimum protocol version required for the \ref destroyed function
  */
  static constexpr std::uint32_t destroyed_since_version = 1;

};

using global_zxdg_imported_v1_t = global_t<zxdg_imported_v1_t>;


/** \brief interface for exporting surfaces

      A global interface used for exporting surfaces that can later be imported
      using xdg_importer.
    
*/
class zxdg_exporter_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_exported_v2_t, surface_t)> export_toplevel;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_exporter_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_exporter_v2_t>;
  friend class global_base_t;

public:
  zxdg_exporter_v2_t() = default;
  zxdg_exporter_v2_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_exporter_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_exporter_v2*() const;

  /** \brief destroy the xdg_exporter object

	Notify the compositor that the xdg_exporter object will no longer be
	used.
      
  */
  std::function<void()> &on_destroy();

  /** \brief export a toplevel surface
      \param id the new xdg_exported object
      \param surface the surface to export

	The export_toplevel request exports the passed surface so that it can later be
	imported via xdg_importer. When called, a new xdg_exported object will
	be created and xdg_exported.handle will be sent immediately. See the
	corresponding interface and event for details.

	A surface may be exported multiple times, and each exported handle may
	be used to create an xdg_imported multiple times. Only xdg_toplevel
        equivalent surfaces may be exported, otherwise an invalid_surface
        protocol error is sent.
      
  */
  std::function<void(zxdg_exported_v2_t, surface_t)> &on_export_toplevel();

  /** \brief Post error: surface is not an xdg_toplevel
  */
  void post_invalid_surface(std::string const& msg);

};

using global_zxdg_exporter_v2_t = global_t<zxdg_exporter_v2_t>;

/** \brief error values

        These errors can be emitted in response to invalid xdg_exporter
        requests.
      
  */
enum class zxdg_exporter_v2_error : uint32_t
  {
  /** \brief surface is not an xdg_toplevel */
  invalid_surface = 0
};


/** \brief interface for importing surfaces

      A global interface used for importing surfaces exported by xdg_exporter.
      With this interface, a client can create a reference to a surface of
      another client.
    
*/
class zxdg_importer_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_imported_v2_t, std::string)> import_toplevel;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_importer_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_importer_v2_t>;
  friend class global_base_t;

public:
  zxdg_importer_v2_t() = default;
  zxdg_importer_v2_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_importer_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_importer_v2*() const;

  /** \brief destroy the xdg_importer object

	Notify the compositor that the xdg_importer object will no longer be
	used.
      
  */
  std::function<void()> &on_destroy();

  /** \brief import a toplevel surface
      \param id the new xdg_imported object
      \param handle the exported surface handle

	The import_toplevel request imports a surface from any client given a handle
	retrieved by exporting said surface using xdg_exporter.export_toplevel.
	When called, a new xdg_imported object will be created. This new object
	represents the imported surface, and the importing client can
	manipulate its relationship using it. See xdg_imported for details.
      
  */
  std::function<void(zxdg_imported_v2_t, std::string)> &on_import_toplevel();

};

using global_zxdg_importer_v2_t = global_t<zxdg_importer_v2_t>;


/** \brief an exported surface handle

      An xdg_exported object represents an exported reference to a surface. The
      exported surface may be referenced as long as the xdg_exported object not
      destroyed. Destroying the xdg_exported invalidates any relationship the
      importer may have established using xdg_imported.
    
*/
class zxdg_exported_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_exported_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_exported_v2_t>;
  friend class global_base_t;

public:
  zxdg_exported_v2_t() = default;
  zxdg_exported_v2_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_exported_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_exported_v2*() const;

  /** \brief unexport the exported surface

	Revoke the previously exported surface. This invalidates any
	relationship the importer may have set up using the xdg_imported created
	given the handle sent via xdg_exported.handle.
      
  */
  std::function<void()> &on_destroy();

  /** \brief the exported surface handle
      \param handle the exported surface handle

	The handle event contains the unique handle of this exported surface
	reference. It may be shared with any client, which then can use it to
	import the surface by calling xdg_importer.import_toplevel. A handle
	may be used to import the surface multiple times.
      
  */
  void handle(std::string const& handle, bool post = true);

  /** \brief Minimum protocol version required for the \ref handle function
  */
  static constexpr std::uint32_t handle_since_version = 1;

};

using global_zxdg_exported_v2_t = global_t<zxdg_exported_v2_t>;


/** \brief an imported surface handle

      An xdg_imported object represents an imported reference to surface exported
      by some client. A client can use this interface to manipulate
      relationships between its own surfaces and the imported surface.
    
*/
class zxdg_imported_v2_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(surface_t)> set_parent_of;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_imported_v2_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_imported_v2_t>;
  friend class global_base_t;

public:
  zxdg_imported_v2_t() = default;
  zxdg_imported_v2_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_imported_v2_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_imported_v2*() const;

  /** \brief destroy the xdg_imported object

	Notify the compositor that it will no longer use the xdg_imported
	object. Any relationship that may have been set up will at this point
	be invalidated.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set as the parent of some surface
      \param surface the child surface

        Set the imported surface as the parent of some surface of the client.
        The passed surface must be an xdg_toplevel equivalent, otherwise an
        invalid_surface protocol error is sent. Calling this function sets up
        a surface to surface relation with the same stacking and positioning
        semantics as xdg_toplevel.set_parent.
      
  */
  std::function<void(surface_t)> &on_set_parent_of();

  /** \brief the imported surface handle has been destroyed

	The imported surface handle has been destroyed and any relationship set
	up has been invalidated. This may happen for various reasons, for
	example if the exported surface or the exported surface handle has been
	destroyed, if the handle used for importing was invalid.
      
  */
  void destroyed(bool post = true);

  /** \brief Minimum protocol version required for the \ref destroyed function
  */
  static constexpr std::uint32_t destroyed_since_version = 1;

  /** \brief Post error: surface is not an xdg_toplevel
  */
  void post_invalid_surface(std::string const& msg);

};

using global_zxdg_imported_v2_t = global_t<zxdg_imported_v2_t>;

/** \brief error values

        These errors can be emitted in response to invalid xdg_imported
        requests.
      
  */
enum class zxdg_imported_v2_error : uint32_t
  {
  /** \brief surface is not an xdg_toplevel */
  invalid_surface = 0
};


/** \brief manage xdg_output objects

      A global factory interface for xdg_output objects.
    
*/
class zxdg_output_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_output_v1_t, output_t)> get_xdg_output;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_output_manager_v1_interface;
  static constexpr const unsigned int max_version = 3;

  friend class global_t<zxdg_output_manager_v1_t>;
  friend class global_base_t;

public:
  zxdg_output_manager_v1_t() = default;
  zxdg_output_manager_v1_t(const client_t& client, uint32_t id, int version = 3);
  zxdg_output_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_output_manager_v1*() const;

  /** \brief destroy the xdg_output_manager object

	Using this request a client can tell the server that it is not
	going to use the xdg_output_manager object anymore.

	Any objects already created through this instance are not affected.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create an xdg output from a wl_output
      \param id 
      \param output 

	This creates a new xdg_output object for the given wl_output.
      
  */
  std::function<void(zxdg_output_v1_t, output_t)> &on_get_xdg_output();

};

using global_zxdg_output_manager_v1_t = global_t<zxdg_output_manager_v1_t>;


/** \brief compositor logical output region

      An xdg_output describes part of the compositor geometry.

      This typically corresponds to a monitor that displays part of the
      compositor space.

      For objects version 3 onwards, after all xdg_output properties have been
      sent (when the object is created and when properties are updated), a
      wl_output.done event is sent. This allows changes to the output
      properties to be seen as atomic, even if they happen via multiple events.
    
*/
class zxdg_output_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_output_v1_interface;
  static constexpr const unsigned int max_version = 3;

  friend class global_t<zxdg_output_v1_t>;
  friend class global_base_t;

public:
  zxdg_output_v1_t() = default;
  zxdg_output_v1_t(const client_t& client, uint32_t id, int version = 3);
  zxdg_output_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_output_v1*() const;

  /** \brief destroy the xdg_output object

	Using this request a client can tell the server that it is not
	going to use the xdg_output object anymore.
      
  */
  std::function<void()> &on_destroy();

  /** \brief position of the output within the global compositor space
      \param x x position within the global compositor space
      \param y y position within the global compositor space

	The position event describes the location of the wl_output within
	the global compositor space.

	The logical_position event is sent after creating an xdg_output
	(see xdg_output_manager.get_xdg_output) and whenever the location
	of the output changes within the global compositor space.
      
  */
  void logical_position(int32_t x, int32_t y, bool post = true);

  /** \brief Minimum protocol version required for the \ref logical_position function
  */
  static constexpr std::uint32_t logical_position_since_version = 1;

  /** \brief size of the output in the global compositor space
      \param width width in global compositor space
      \param height height in global compositor space

	The logical_size event describes the size of the output in the
	global compositor space.

	For example, a surface without any buffer scale, transformation
	nor rotation set, with the size matching the logical_size will
	have the same size as the corresponding output when displayed.

	Most regular Wayland clients should not pay attention to the
	logical size and would rather rely on xdg_shell interfaces.

	Some clients such as Xwayland, however, need this to configure
	their surfaces in the global compositor space as the compositor
	may apply a different scale from what is advertised by the output
	scaling property (to achieve fractional scaling, for example).

	For example, for a wl_output mode 3840×2160 and a scale factor 2:

	- A compositor not scaling the surface buffers will advertise a
	  logical size of 3840×2160,

	- A compositor automatically scaling the surface buffers will
	  advertise a logical size of 1920×1080,

	- A compositor using a fractional scale of 1.5 will advertise a
	  logical size of 2560×1440.

	For example, for a wl_output mode 1920×1080 and a 90 degree rotation,
	the compositor will advertise a logical size of 1080x1920.

	The logical_size event is sent after creating an xdg_output
	(see xdg_output_manager.get_xdg_output) and whenever the logical
	size of the output changes, either as a result of a change in the
	applied scale or because of a change in the corresponding output
	mode(see wl_output.mode) or transform (see wl_output.transform).
      
  */
  void logical_size(int32_t width, int32_t height, bool post = true);

  /** \brief Minimum protocol version required for the \ref logical_size function
  */
  static constexpr std::uint32_t logical_size_since_version = 1;

  /** \brief all information about the output have been sent

	This event is sent after all other properties of an xdg_output
	have been sent.

	This allows changes to the xdg_output properties to be seen as
	atomic, even if they happen via multiple events.

	For objects version 3 onwards, this event is deprecated. Compositors
	are not required to send it anymore and must send wl_output.done
	instead.
      
  */
  void done(bool post = true);

  /** \brief Minimum protocol version required for the \ref done function
  */
  static constexpr std::uint32_t done_since_version = 1;

  /** \brief name of this output
      \param name output name

	Many compositors will assign names to their outputs, show them to the
	user, allow them to be configured by name, etc. The client may wish to
	know this name as well to offer the user similar behaviors.

	The naming convention is compositor defined, but limited to
	alphanumeric characters and dashes (-). Each name is unique among all
	wl_output globals, but if a wl_output global is destroyed the same name
	may be reused later. The names will also remain consistent across
	sessions with the same hardware and software configuration.

	Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
	not assume that the name is a reflection of an underlying DRM
	connector, X11 connection, etc.

	The name event is sent after creating an xdg_output (see
	xdg_output_manager.get_xdg_output). This event is only sent once per
	xdg_output, and the name does not change over the lifetime of the
	wl_output global.
      
  */
  void name(std::string const& name, bool post = true);

  /** \brief Minimum protocol version required for the \ref name function
  */
  static constexpr std::uint32_t name_since_version = 2;

  /** \brief Check whether the \ref name function is available with
      the currently bound version of the protocol
  */
  bool can_name() const;

  /** \brief human-readable description of this output
      \param description output description

	Many compositors can produce human-readable descriptions of their
	outputs.  The client may wish to know this description as well, to
	communicate the user for various purposes.

	The description is a UTF-8 string with no convention defined for its
	contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
	output via :1'.

	The description event is sent after creating an xdg_output (see
	xdg_output_manager.get_xdg_output) and whenever the description
	changes. The description is optional, and may not be sent at all.

	For objects of version 2 and lower, this event is only sent once per
	xdg_output, and the description does not change over the lifetime of
	the wl_output global.
      
  */
  void description(std::string const& description, bool post = true);

  /** \brief Minimum protocol version required for the \ref description function
  */
  static constexpr std::uint32_t description_since_version = 2;

  /** \brief Check whether the \ref description function is available with
      the currently bound version of the protocol
  */
  bool can_description() const;

};

using global_zxdg_output_v1_t = global_t<zxdg_output_v1_t>;


/** \brief create desktop-style surfaces

      xdg_shell allows clients to turn a wl_surface into a "real window"
      which can be dragged, resized, stacked, and moved around by the
      user. Everything about this interface is suited towards traditional
      desktop environments.
    
*/
class zxdg_shell_v6_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_positioner_v6_t)> create_positioner;
    std::function<void(zxdg_surface_v6_t, surface_t)> get_xdg_surface;
    std::function<void(uint32_t)> pong;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_shell_v6_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_shell_v6_t>;
  friend class global_base_t;

public:
  zxdg_shell_v6_t() = default;
  zxdg_shell_v6_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_shell_v6_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_shell_v6*() const;

  /** \brief destroy xdg_shell

	Destroy this xdg_shell object.

	Destroying a bound xdg_shell object while there are surfaces
	still alive created by this xdg_shell object instance is illegal
	and will result in a protocol error.
      
  */
  std::function<void()> &on_destroy();

  /** \brief create a positioner object
      \param id 

	Create a positioner object. A positioner object is used to position
	surfaces relative to some parent surface. See the interface description
	and xdg_surface.get_popup for details.
      
  */
  std::function<void(zxdg_positioner_v6_t)> &on_create_positioner();

  /** \brief create a shell surface from a surface
      \param id 
      \param surface 

	This creates an xdg_surface for the given surface. While xdg_surface
	itself is not a role, the corresponding surface may only be assigned
	a role extending xdg_surface, such as xdg_toplevel or xdg_popup.

	This creates an xdg_surface for the given surface. An xdg_surface is
	used as basis to define a role to a given surface, such as xdg_toplevel
	or xdg_popup. It also manages functionality shared between xdg_surface
	based surface roles.

	See the documentation of xdg_surface for more details about what an
	xdg_surface is and how it is used.
      
  */
  std::function<void(zxdg_surface_v6_t, surface_t)> &on_get_xdg_surface();

  /** \brief respond to a ping event
      \param serial serial of the ping event

	A client must respond to a ping event with a pong request or
	the client may be deemed unresponsive. See xdg_shell.ping.
      
  */
  std::function<void(uint32_t)> &on_pong();

  /** \brief check if the client is alive
      \param serial pass this to the pong request

	The ping event asks the client if it's still alive. Pass the
	serial specified in the event back to the compositor by sending
	a "pong" request back with the specified serial. See xdg_shell.ping.

	Compositors can use this to determine if the client is still
	alive. It's unspecified what will happen if the client doesn't
	respond to the ping request, or in what timeframe. Clients should
	try to respond in a reasonable amount of time.

	A compositor is free to ping in any way it wants, but a client must
	always respond to any xdg_shell object it created.
      
  */
  void ping(uint32_t serial, bool post = true);

  /** \brief Minimum protocol version required for the \ref ping function
  */
  static constexpr std::uint32_t ping_since_version = 1;

  /** \brief Post error: given wl_surface has another role
  */
  void post_role(std::string const& msg);

  /** \brief Post error: xdg_shell was destroyed before children
  */
  void post_defunct_surfaces(std::string const& msg);

  /** \brief Post error: the client tried to map or destroy a non-topmost popup
  */
  void post_not_the_topmost_popup(std::string const& msg);

  /** \brief Post error: the client specified an invalid popup parent surface
  */
  void post_invalid_popup_parent(std::string const& msg);

  /** \brief Post error: the client provided an invalid surface state
  */
  void post_invalid_surface_state(std::string const& msg);

  /** \brief Post error: the client provided an invalid positioner
  */
  void post_invalid_positioner(std::string const& msg);

};

using global_zxdg_shell_v6_t = global_t<zxdg_shell_v6_t>;

/** \brief 

  */
enum class zxdg_shell_v6_error : uint32_t
  {
  /** \brief given wl_surface has another role */
  role = 0,
  /** \brief xdg_shell was destroyed before children */
  defunct_surfaces = 1,
  /** \brief the client tried to map or destroy a non-topmost popup */
  not_the_topmost_popup = 2,
  /** \brief the client specified an invalid popup parent surface */
  invalid_popup_parent = 3,
  /** \brief the client provided an invalid surface state */
  invalid_surface_state = 4,
  /** \brief the client provided an invalid positioner */
  invalid_positioner = 5
};


/** \brief child surface positioner

      The xdg_positioner provides a collection of rules for the placement of a
      child surface relative to a parent surface. Rules can be defined to ensure
      the child surface remains within the visible area's borders, and to
      specify how the child surface changes its position, such as sliding along
      an axis, or flipping around a rectangle. These positioner-created rules are
      constrained by the requirement that a child surface must intersect with or
      be at least partially adjacent to its parent surface.

      See the various requests for details about possible rules.

      At the time of the request, the compositor makes a copy of the rules
      specified by the xdg_positioner. Thus, after the request is complete the
      xdg_positioner object can be destroyed or reused; further changes to the
      object will have no effect on previous usages.

      For an xdg_positioner object to be considered complete, it must have a
      non-zero size set by set_size, and a non-zero anchor rectangle set by
      set_anchor_rect. Passing an incomplete xdg_positioner object when
      positioning a surface raises an error.
    
*/
class zxdg_positioner_v6_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(int32_t, int32_t)> set_size;
    std::function<void(int32_t, int32_t, int32_t, int32_t)> set_anchor_rect;
    std::function<void(zxdg_positioner_v6_anchor)> set_anchor;
    std::function<void(zxdg_positioner_v6_gravity)> set_gravity;
    std::function<void(zxdg_positioner_v6_constraint_adjustment)> set_constraint_adjustment;
    std::function<void(int32_t, int32_t)> set_offset;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_positioner_v6_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_positioner_v6_t>;
  friend class global_base_t;

public:
  zxdg_positioner_v6_t() = default;
  zxdg_positioner_v6_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_positioner_v6_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_positioner_v6*() const;

  /** \brief destroy the xdg_positioner object

	Notify the compositor that the xdg_positioner will no longer be used.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set the size of the to-be positioned rectangle
      \param width width of positioned rectangle
      \param height height of positioned rectangle

	Set the size of the surface that is to be positioned with the positioner
	object. The size is in surface-local coordinates and corresponds to the
	window geometry. See xdg_surface.set_window_geometry.

	If a zero or negative size is set the invalid_input error is raised.
      
  */
  std::function<void(int32_t, int32_t)> &on_set_size();

  /** \brief set the anchor rectangle within the parent surface
      \param x x position of anchor rectangle
      \param y y position of anchor rectangle
      \param width width of anchor rectangle
      \param height height of anchor rectangle

	Specify the anchor rectangle within the parent surface that the child
	surface will be placed relative to. The rectangle is relative to the
	window geometry as defined by xdg_surface.set_window_geometry of the
	parent surface. The rectangle must be at least 1x1 large.

	When the xdg_positioner object is used to position a child surface, the
	anchor rectangle may not extend outside the window geometry of the
	positioned child's parent surface.

	If a zero or negative size is set the invalid_input error is raised.
      
  */
  std::function<void(int32_t, int32_t, int32_t, int32_t)> &on_set_anchor_rect();

  /** \brief set anchor rectangle anchor edges
      \param anchor bit mask of anchor edges

	Defines a set of edges for the anchor rectangle. These are used to
	derive an anchor point that the child surface will be positioned
	relative to. If two orthogonal edges are specified (e.g. 'top' and
	'left'), then the anchor point will be the intersection of the edges
	(e.g. the top left position of the rectangle); otherwise, the derived
	anchor point will be centered on the specified edge, or in the center of
	the anchor rectangle if no edge is specified.

	If two parallel anchor edges are specified (e.g. 'left' and 'right'),
	the invalid_input error is raised.
      
  */
  std::function<void(zxdg_positioner_v6_anchor)> &on_set_anchor();

  /** \brief set child surface gravity
      \param gravity bit mask of gravity directions

	Defines in what direction a surface should be positioned, relative to
	the anchor point of the parent surface. If two orthogonal gravities are
	specified (e.g. 'bottom' and 'right'), then the child surface will be
	placed in the specified direction; otherwise, the child surface will be
	centered over the anchor point on any axis that had no gravity
	specified.

	If two parallel gravities are specified (e.g. 'left' and 'right'), the
	invalid_input error is raised.
      
  */
  std::function<void(zxdg_positioner_v6_gravity)> &on_set_gravity();

  /** \brief set the adjustment to be done when constrained
      \param constraint_adjustment bit mask of constraint adjustments

	Specify how the window should be positioned if the originally intended
	position caused the surface to be constrained, meaning at least
	partially outside positioning boundaries set by the compositor. The
	adjustment is set by constructing a bitmask describing the adjustment to
	be made when the surface is constrained on that axis.

	If no bit for one axis is set, the compositor will assume that the child
	surface should not change its position on that axis when constrained.

	If more than one bit for one axis is set, the order of how adjustments
	are applied is specified in the corresponding adjustment descriptions.

	The default adjustment is none.
      
  */
  std::function<void(zxdg_positioner_v6_constraint_adjustment)> &on_set_constraint_adjustment();

  /** \brief set surface position offset
      \param x surface position x offset
      \param y surface position y offset

	Specify the surface position offset relative to the position of the
	anchor on the anchor rectangle and the anchor on the surface. For
	example if the anchor of the anchor rectangle is at (x, y), the surface
	has the gravity bottom|right, and the offset is (ox, oy), the calculated
	surface position will be (x + ox, y + oy). The offset position of the
	surface is the one used for constraint testing. See
	set_constraint_adjustment.

	An example use case is placing a popup menu on top of a user interface
	element, while aligning the user interface element of the parent surface
	with some user interface element placed somewhere in the popup surface.
      
  */
  std::function<void(int32_t, int32_t)> &on_set_offset();

  /** \brief Post error: invalid input provided
  */
  void post_invalid_input(std::string const& msg);

};

using global_zxdg_positioner_v6_t = global_t<zxdg_positioner_v6_t>;

/** \brief 

  */
enum class zxdg_positioner_v6_error : uint32_t
  {
  /** \brief invalid input provided */
  invalid_input = 0
};

/** \brief 

  */
struct zxdg_positioner_v6_anchor : public wayland::detail::bitfield<4, 37>
{
  zxdg_positioner_v6_anchor(const wayland::detail::bitfield<4, 37> &b)
    : wayland::detail::bitfield<4, 37>(b) {}
  zxdg_positioner_v6_anchor(const uint32_t value)
    : wayland::detail::bitfield<4, 37>(value) {}
  /** \brief the center of the anchor rectangle */
  static const wayland::detail::bitfield<4, 37> none;
  /** \brief the top edge of the anchor rectangle */
  static const wayland::detail::bitfield<4, 37> top;
  /** \brief the bottom edge of the anchor rectangle */
  static const wayland::detail::bitfield<4, 37> bottom;
  /** \brief the left edge of the anchor rectangle */
  static const wayland::detail::bitfield<4, 37> left;
  /** \brief the right edge of the anchor rectangle */
  static const wayland::detail::bitfield<4, 37> right;
};

/** \brief 

  */
struct zxdg_positioner_v6_gravity : public wayland::detail::bitfield<4, 38>
{
  zxdg_positioner_v6_gravity(const wayland::detail::bitfield<4, 38> &b)
    : wayland::detail::bitfield<4, 38>(b) {}
  zxdg_positioner_v6_gravity(const uint32_t value)
    : wayland::detail::bitfield<4, 38>(value) {}
  /** \brief center over the anchor edge */
  static const wayland::detail::bitfield<4, 38> none;
  /** \brief position above the anchor edge */
  static const wayland::detail::bitfield<4, 38> top;
  /** \brief position below the anchor edge */
  static const wayland::detail::bitfield<4, 38> bottom;
  /** \brief position to the left of the anchor edge */
  static const wayland::detail::bitfield<4, 38> left;
  /** \brief position to the right of the anchor edge */
  static const wayland::detail::bitfield<4, 38> right;
};

/** \brief constraint adjustments

	The constraint adjustment value define ways the compositor will adjust
	the position of the surface, if the unadjusted position would result
	in the surface being partly constrained.

	Whether a surface is considered 'constrained' is left to the compositor
	to determine. For example, the surface may be partly outside the
	compositor's defined 'work area', thus necessitating the child surface's
	position be adjusted until it is entirely inside the work area.

	The adjustments can be combined, according to a defined precedence: 1)
	Flip, 2) Slide, 3) Resize.
      
  */
struct zxdg_positioner_v6_constraint_adjustment : public wayland::detail::bitfield<6, 39>
{
  zxdg_positioner_v6_constraint_adjustment(const wayland::detail::bitfield<6, 39> &b)
    : wayland::detail::bitfield<6, 39>(b) {}
  zxdg_positioner_v6_constraint_adjustment(const uint32_t value)
    : wayland::detail::bitfield<6, 39>(value) {}
  static const wayland::detail::bitfield<6, 39> none;
  static const wayland::detail::bitfield<6, 39> slide_x;
  static const wayland::detail::bitfield<6, 39> slide_y;
  static const wayland::detail::bitfield<6, 39> flip_x;
  static const wayland::detail::bitfield<6, 39> flip_y;
  static const wayland::detail::bitfield<6, 39> resize_x;
  static const wayland::detail::bitfield<6, 39> resize_y;
};


/** \brief desktop user interface surface base interface

      An interface that may be implemented by a wl_surface, for
      implementations that provide a desktop-style user interface.

      It provides a base set of functionality required to construct user
      interface elements requiring management by the compositor, such as
      toplevel windows, menus, etc. The types of functionality are split into
      xdg_surface roles.

      Creating an xdg_surface does not set the role for a wl_surface. In order
      to map an xdg_surface, the client must create a role-specific object
      using, e.g., get_toplevel, get_popup. The wl_surface for any given
      xdg_surface can have at most one role, and may not be assigned any role
      not based on xdg_surface.

      A role must be assigned before any other requests are made to the
      xdg_surface object.

      The client must call wl_surface.commit on the corresponding wl_surface
      for the xdg_surface state to take effect.

      Creating an xdg_surface from a wl_surface which has a buffer attached or
      committed is a client error, and any attempts by a client to attach or
      manipulate a buffer prior to the first xdg_surface.configure call must
      also be treated as errors.

      For a surface to be mapped by the compositor, the following conditions
      must be met: (1) the client has assigned an xdg_surface based role to the
      surface, (2) the client has set and committed the xdg_surface state and
      the role dependent state to the surface and (3) the client has committed a
      buffer to the surface.
    
*/
class zxdg_surface_v6_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_toplevel_v6_t)> get_toplevel;
    std::function<void(zxdg_popup_v6_t, zxdg_surface_v6_t, zxdg_positioner_v6_t)> get_popup;
    std::function<void(int32_t, int32_t, int32_t, int32_t)> set_window_geometry;
    std::function<void(uint32_t)> ack_configure;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_surface_v6_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_surface_v6_t>;
  friend class global_base_t;

public:
  zxdg_surface_v6_t() = default;
  zxdg_surface_v6_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_surface_v6_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_surface_v6*() const;

  /** \brief destroy the xdg_surface

	Destroy the xdg_surface object. An xdg_surface must only be destroyed
	after its role object has been destroyed.
      
  */
  std::function<void()> &on_destroy();

  /** \brief assign the xdg_toplevel surface role
      \param id 

	This creates an xdg_toplevel object for the given xdg_surface and gives
	the associated wl_surface the xdg_toplevel role.

	See the documentation of xdg_toplevel for more details about what an
	xdg_toplevel is and how it is used.
      
  */
  std::function<void(zxdg_toplevel_v6_t)> &on_get_toplevel();

  /** \brief assign the xdg_popup surface role
      \param id 
      \param parent 
      \param positioner 

	This creates an xdg_popup object for the given xdg_surface and gives the
	associated wl_surface the xdg_popup role.

	See the documentation of xdg_popup for more details about what an
	xdg_popup is and how it is used.
      
  */
  std::function<void(zxdg_popup_v6_t, zxdg_surface_v6_t, zxdg_positioner_v6_t)> &on_get_popup();

  /** \brief set the new window geometry
      \param x 
      \param y 
      \param width 
      \param height 

	The window geometry of a surface is its "visible bounds" from the
	user's perspective. Client-side decorations often have invisible
	portions like drop-shadows which should be ignored for the
	purposes of aligning, placing and constraining windows.

	The window geometry is double buffered, and will be applied at the
	time wl_surface.commit of the corresponding wl_surface is called.

	Once the window geometry of the surface is set, it is not possible to
	unset it, and it will remain the same until set_window_geometry is
	called again, even if a new subsurface or buffer is attached.

	If never set, the value is the full bounds of the surface,
	including any subsurfaces. This updates dynamically on every
	commit. This unset is meant for extremely simple clients.

	The arguments are given in the surface-local coordinate space of
	the wl_surface associated with this xdg_surface.

	The width and height must be greater than zero. Setting an invalid size
	will raise an error. When applied, the effective window geometry will be
	the set window geometry clamped to the bounding rectangle of the
	combined geometry of the surface of the xdg_surface and the associated
	subsurfaces.
      
  */
  std::function<void(int32_t, int32_t, int32_t, int32_t)> &on_set_window_geometry();

  /** \brief ack a configure event
      \param serial the serial from the configure event

	When a configure event is received, if a client commits the
	surface in response to the configure event, then the client
	must make an ack_configure request sometime before the commit
	request, passing along the serial of the configure event.

	For instance, for toplevel surfaces the compositor might use this
	information to move a surface to the top left only when the client has
	drawn itself for the maximized or fullscreen state.

	If the client receives multiple configure events before it
	can respond to one, it only has to ack the last configure event.

	A client is not required to commit immediately after sending
	an ack_configure request - it may even ack_configure several times
	before its next surface commit.

	A client may send multiple ack_configure requests before committing, but
	only the last request sent before a commit indicates which configure
	event the client really is responding to.
      
  */
  std::function<void(uint32_t)> &on_ack_configure();

  /** \brief suggest a surface change
      \param serial serial of the configure event

	The configure event marks the end of a configure sequence. A configure
	sequence is a set of one or more events configuring the state of the
	xdg_surface, including the final xdg_surface.configure event.

	Where applicable, xdg_surface surface roles will during a configure
	sequence extend this event as a latched state sent as events before the
	xdg_surface.configure event. Such events should be considered to make up
	a set of atomically applied configuration states, where the
	xdg_surface.configure commits the accumulated state.

	Clients should arrange their surface for the new states, and then send
	an ack_configure request with the serial sent in this configure event at
	some point before committing the new surface.

	If the client receives multiple configure events before it can respond
	to one, it is free to discard all but the last event it received.
      
  */
  void configure(uint32_t serial, bool post = true);

  /** \brief Minimum protocol version required for the \ref configure function
  */
  static constexpr std::uint32_t configure_since_version = 1;

  /** \brief Post error: 
  */
  void post_not_constructed(std::string const& msg);

  /** \brief Post error: 
  */
  void post_already_constructed(std::string const& msg);

  /** \brief Post error: 
  */
  void post_unconfigured_buffer(std::string const& msg);

};

using global_zxdg_surface_v6_t = global_t<zxdg_surface_v6_t>;

/** \brief 

  */
enum class zxdg_surface_v6_error : uint32_t
  {
  not_constructed = 1,
  already_constructed = 2,
  unconfigured_buffer = 3
};


/** \brief toplevel surface

      This interface defines an xdg_surface role which allows a surface to,
      among other things, set window-like properties such as maximize,
      fullscreen, and minimize, set application-specific metadata like title and
      id, and well as trigger user interactive operations such as interactive
      resize and move.
    
*/
class zxdg_toplevel_v6_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zxdg_toplevel_v6_t)> set_parent;
    std::function<void(std::string)> set_title;
    std::function<void(std::string)> set_app_id;
    std::function<void(seat_t, uint32_t, int32_t, int32_t)> show_window_menu;
    std::function<void(seat_t, uint32_t)> move;
    std::function<void(seat_t, uint32_t, zxdg_toplevel_v6_resize_edge)> resize;
    std::function<void(int32_t, int32_t)> set_max_size;
    std::function<void(int32_t, int32_t)> set_min_size;
    std::function<void()> set_maximized;
    std::function<void()> unset_maximized;
    std::function<void(output_t)> set_fullscreen;
    std::function<void()> unset_fullscreen;
    std::function<void()> set_minimized;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_toplevel_v6_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_toplevel_v6_t>;
  friend class global_base_t;

public:
  zxdg_toplevel_v6_t() = default;
  zxdg_toplevel_v6_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_toplevel_v6_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_toplevel_v6*() const;

  /** \brief destroy the xdg_toplevel

	Unmap and destroy the window. The window will be effectively
	hidden from the user's point of view, and all state like
	maximization, fullscreen, and so on, will be lost.
      
  */
  std::function<void()> &on_destroy();

  /** \brief set the parent of this surface
      \param parent 

	Set the "parent" of this surface. This window should be stacked
	above a parent. The parent surface must be mapped as long as this
	surface is mapped.

	Parent windows should be set on dialogs, toolboxes, or other
	"auxiliary" surfaces, so that the parent is raised when the dialog
	is raised.
      
  */
  std::function<void(zxdg_toplevel_v6_t)> &on_set_parent();

  /** \brief set surface title
      \param title 

	Set a short title for the surface.

	This string may be used to identify the surface in a task bar,
	window list, or other user interface elements provided by the
	compositor.

	The string must be encoded in UTF-8.
      
  */
  std::function<void(std::string)> &on_set_title();

  /** \brief set application ID
      \param app_id 

	Set an application identifier for the surface.

	The app ID identifies the general class of applications to which
	the surface belongs. The compositor can use this to group multiple
	surfaces together, or to determine how to launch a new application.

	For D-Bus activatable applications, the app ID is used as the D-Bus
	service name.

	The compositor shell will try to group application surfaces together
	by their app ID. As a best practice, it is suggested to select app
	ID's that match the basename of the application's .desktop file.
	For example, "org.freedesktop.FooViewer" where the .desktop file is
	"org.freedesktop.FooViewer.desktop".

	See the desktop-entry specification [0] for more details on
	application identifiers and how they relate to well-known D-Bus
	names and .desktop files.

	[0] http://standards.freedesktop.org/desktop-entry-spec/
      
  */
  std::function<void(std::string)> &on_set_app_id();

  /** \brief show the window menu
      \param seat the wl_seat of the user event
      \param serial the serial of the user event
      \param x the x position to pop up the window menu at
      \param y the y position to pop up the window menu at

	Clients implementing client-side decorations might want to show
	a context menu when right-clicking on the decorations, giving the
	user a menu that they can use to maximize or minimize the window.

	This request asks the compositor to pop up such a window menu at
	the given position, relative to the local surface coordinates of
	the parent surface. There are no guarantees as to what menu items
	the window menu contains.

	This request must be used in response to some sort of user action
	like a button press, key press, or touch down event.
      
  */
  std::function<void(seat_t, uint32_t, int32_t, int32_t)> &on_show_window_menu();

  /** \brief start an interactive move
      \param seat the wl_seat of the user event
      \param serial the serial of the user event

	Start an interactive, user-driven move of the surface.

	This request must be used in response to some sort of user action
	like a button press, key press, or touch down event. The passed
	serial is used to determine the type of interactive move (touch,
	pointer, etc).

	The server may ignore move requests depending on the state of
	the surface (e.g. fullscreen or maximized), or if the passed serial
	is no longer valid.

	If triggered, the surface will lose the focus of the device
	(wl_pointer, wl_touch, etc) used for the move. It is up to the
	compositor to visually indicate that the move is taking place, such as
	updating a pointer cursor, during the move. There is no guarantee
	that the device focus will return when the move is completed.
      
  */
  std::function<void(seat_t, uint32_t)> &on_move();

  /** \brief start an interactive resize
      \param seat the wl_seat of the user event
      \param serial the serial of the user event
      \param edges which edge or corner is being dragged

	Start a user-driven, interactive resize of the surface.

	This request must be used in response to some sort of user action
	like a button press, key press, or touch down event. The passed
	serial is used to determine the type of interactive resize (touch,
	pointer, etc).

	The server may ignore resize requests depending on the state of
	the surface (e.g. fullscreen or maximized).

	If triggered, the client will receive configure events with the
	"resize" state enum value and the expected sizes. See the "resize"
	enum value for more details about what is required. The client
	must also acknowledge configure events using "ack_configure". After
	the resize is completed, the client will receive another "configure"
	event without the resize state.

	If triggered, the surface also will lose the focus of the device
	(wl_pointer, wl_touch, etc) used for the resize. It is up to the
	compositor to visually indicate that the resize is taking place,
	such as updating a pointer cursor, during the resize. There is no
	guarantee that the device focus will return when the resize is
	completed.

	The edges parameter specifies how the surface should be resized,
	and is one of the values of the resize_edge enum. The compositor
	may use this information to update the surface position for
	example when dragging the top left corner. The compositor may also
	use this information to adapt its behavior, e.g. choose an
	appropriate cursor image.
      
  */
  std::function<void(seat_t, uint32_t, zxdg_toplevel_v6_resize_edge)> &on_resize();

  /** \brief set the maximum size
      \param width 
      \param height 

	Set a maximum size for the window.

	The client can specify a maximum size so that the compositor does
	not try to configure the window beyond this size.

	The width and height arguments are in window geometry coordinates.
	See xdg_surface.set_window_geometry.

	Values set in this way are double-buffered. They will get applied
	on the next commit.

	The compositor can use this information to allow or disallow
	different states like maximize or fullscreen and draw accurate
	animations.

	Similarly, a tiling window manager may use this information to
	place and resize client windows in a more effective way.

	The client should not rely on the compositor to obey the maximum
	size. The compositor may decide to ignore the values set by the
	client and request a larger size.

	If never set, or a value of zero in the request, means that the
	client has no expected maximum size in the given dimension.
	As a result, a client wishing to reset the maximum size
	to an unspecified state can use zero for width and height in the
	request.

	Requesting a maximum size to be smaller than the minimum size of
	a surface is illegal and will result in a protocol error.

	The width and height must be greater than or equal to zero. Using
	strictly negative values for width and height will result in a
	protocol error.
      
  */
  std::function<void(int32_t, int32_t)> &on_set_max_size();

  /** \brief set the minimum size
      \param width 
      \param height 

	Set a minimum size for the window.

	The client can specify a minimum size so that the compositor does
	not try to configure the window below this size.

	The width and height arguments are in window geometry coordinates.
	See xdg_surface.set_window_geometry.

	Values set in this way are double-buffered. They will get applied
	on the next commit.

	The compositor can use this information to allow or disallow
	different states like maximize or fullscreen and draw accurate
	animations.

	Similarly, a tiling window manager may use this information to
	place and resize client windows in a more effective way.

	The client should not rely on the compositor to obey the minimum
	size. The compositor may decide to ignore the values set by the
	client and request a smaller size.

	If never set, or a value of zero in the request, means that the
	client has no expected minimum size in the given dimension.
	As a result, a client wishing to reset the minimum size
	to an unspecified state can use zero for width and height in the
	request.

	Requesting a minimum size to be larger than the maximum size of
	a surface is illegal and will result in a protocol error.

	The width and height must be greater than or equal to zero. Using
	strictly negative values for width and height will result in a
	protocol error.
      
  */
  std::function<void(int32_t, int32_t)> &on_set_min_size();

  /** \brief maximize the window

	Maximize the surface.

	After requesting that the surface should be maximized, the compositor
	will respond by emitting a configure event with the "maximized" state
	and the required window geometry. The client should then update its
	content, drawing it in a maximized state, i.e. without shadow or other
	decoration outside of the window geometry. The client must also
	acknowledge the configure when committing the new content (see
	ack_configure).

	It is up to the compositor to decide how and where to maximize the
	surface, for example which output and what region of the screen should
	be used.

	If the surface was already maximized, the compositor will still emit
	a configure event with the "maximized" state.
      
  */
  std::function<void()> &on_set_maximized();

  /** \brief unmaximize the window

	Unmaximize the surface.

	After requesting that the surface should be unmaximized, the compositor
	will respond by emitting a configure event without the "maximized"
	state. If available, the compositor will include the window geometry
	dimensions the window had prior to being maximized in the configure
	request. The client must then update its content, drawing it in a
	regular state, i.e. potentially with shadow, etc. The client must also
	acknowledge the configure when committing the new content (see
	ack_configure).

	It is up to the compositor to position the surface after it was
	unmaximized; usually the position the surface had before maximizing, if
	applicable.

	If the surface was already not maximized, the compositor will still
	emit a configure event without the "maximized" state.
      
  */
  std::function<void()> &on_unset_maximized();

  /** \brief set the window as fullscreen on a monitor
      \param output 

	Make the surface fullscreen.

	You can specify an output that you would prefer to be fullscreen.
	If this value is NULL, it's up to the compositor to choose which
	display will be used to map this surface.

	If the surface doesn't cover the whole output, the compositor will
	position the surface in the center of the output and compensate with
	black borders filling the rest of the output.
      
  */
  std::function<void(output_t)> &on_set_fullscreen();

  /** \brief 

  */
  std::function<void()> &on_unset_fullscreen();

  /** \brief set the window as minimized

	Request that the compositor minimize your surface. There is no
	way to know if the surface is currently minimized, nor is there
	any way to unset minimization on this surface.

	If you are looking to throttle redrawing when minimized, please
	instead use the wl_surface.frame event for this, as this will
	also work with live previews on windows in Alt-Tab, Expose or
	similar compositor features.
      
  */
  std::function<void()> &on_set_minimized();

  /** \brief suggest a surface change
      \param width 
      \param height 
      \param states 

	This configure event asks the client to resize its toplevel surface or
	to change its state. The configured state should not be applied
	immediately. See xdg_surface.configure for details.

	The width and height arguments specify a hint to the window
	about how its surface should be resized in window geometry
	coordinates. See set_window_geometry.

	If the width or height arguments are zero, it means the client
	should decide its own window dimension. This may happen when the
	compositor needs to configure the state of the surface but doesn't
	have any information about any previous or expected dimension.

	The states listed in the event specify how the width/height
	arguments should be interpreted, and possibly how it should be
	drawn.

	Clients must send an ack_configure in response to this event. See
	xdg_surface.configure and xdg_surface.ack_configure for details.
      
  */
  void configure(int32_t width, int32_t height, array_t const& states, bool post = true);

  /** \brief Minimum protocol version required for the \ref configure function
  */
  static constexpr std::uint32_t configure_since_version = 1;

  /** \brief surface wants to be closed

	The close event is sent by the compositor when the user
	wants the surface to be closed. This should be equivalent to
	the user clicking the close button in client-side decorations,
	if your application has any.

	This is only a request that the user intends to close the
	window. The client may choose to ignore this request, or show
	a dialog to ask the user to save their data, etc.
      
  */
  void close(bool post = true);

  /** \brief Minimum protocol version required for the \ref close function
  */
  static constexpr std::uint32_t close_since_version = 1;

};

using global_zxdg_toplevel_v6_t = global_t<zxdg_toplevel_v6_t>;

/** \brief edge values for resizing

	These values are used to indicate which edge of a surface
	is being dragged in a resize operation.
      
  */
struct zxdg_toplevel_v6_resize_edge : public wayland::detail::bitfield<4, 41>
{
  zxdg_toplevel_v6_resize_edge(const wayland::detail::bitfield<4, 41> &b)
    : wayland::detail::bitfield<4, 41>(b) {}
  zxdg_toplevel_v6_resize_edge(const uint32_t value)
    : wayland::detail::bitfield<4, 41>(value) {}
  static const wayland::detail::bitfield<4, 41> none;
  static const wayland::detail::bitfield<4, 41> top;
  static const wayland::detail::bitfield<4, 41> bottom;
  static const wayland::detail::bitfield<4, 41> left;
  static const wayland::detail::bitfield<4, 41> top_left;
  static const wayland::detail::bitfield<4, 41> bottom_left;
  static const wayland::detail::bitfield<4, 41> right;
  static const wayland::detail::bitfield<4, 41> top_right;
  static const wayland::detail::bitfield<4, 41> bottom_right;
};

/** \brief types of state on the surface

	The different state values used on the surface. This is designed for
	state values like maximized, fullscreen. It is paired with the
	configure event to ensure that both the client and the compositor
	setting the state can be synchronized.

	States set in this way are double-buffered. They will get applied on
	the next commit.
      
  */
enum class zxdg_toplevel_v6_state : uint32_t
  {
  /** \brief the surface is maximized */
  maximized = 1,
  /** \brief the surface is fullscreen */
  fullscreen = 2,
  /** \brief the surface is being resized */
  resizing = 3,
  /** \brief the surface is now activated */
  activated = 4
};


/** \brief short-lived, popup surfaces for menus

      A popup surface is a short-lived, temporary surface. It can be used to
      implement for example menus, popovers, tooltips and other similar user
      interface concepts.

      A popup can be made to take an explicit grab. See xdg_popup.grab for
      details.

      When the popup is dismissed, a popup_done event will be sent out, and at
      the same time the surface will be unmapped. See the xdg_popup.popup_done
      event for details.

      Explicitly destroying the xdg_popup object will also dismiss the popup and
      unmap the surface. Clients that want to dismiss the popup when another
      surface of their own is clicked should dismiss the popup using the destroy
      request.

      The parent surface must have either the xdg_toplevel or xdg_popup surface
      role.

      A newly created xdg_popup will be stacked on top of all previously created
      xdg_popup surfaces associated with the same xdg_toplevel.

      The parent of an xdg_popup must be mapped (see the xdg_surface
      description) before the xdg_popup itself.

      The x and y arguments passed when creating the popup object specify
      where the top left of the popup should be placed, relative to the
      local surface coordinates of the parent surface. See
      xdg_surface.get_popup. An xdg_popup must intersect with or be at least
      partially adjacent to its parent surface.

      The client must call wl_surface.commit on the corresponding wl_surface
      for the xdg_popup state to take effect.
    
*/
class zxdg_popup_v6_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(seat_t, uint32_t)> grab;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zxdg_popup_v6_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zxdg_popup_v6_t>;
  friend class global_base_t;

public:
  zxdg_popup_v6_t() = default;
  zxdg_popup_v6_t(const client_t& client, uint32_t id, int version = 1);
  zxdg_popup_v6_t(const resource_t &resource);

  static const std::string interface_name;

  operator zxdg_popup_v6*() const;

  /** \brief remove xdg_popup interface

	This destroys the popup. Explicitly destroying the xdg_popup
	object will also dismiss the popup, and unmap the surface.

	If this xdg_popup is not the "topmost" popup, a protocol error
	will be sent.
      
  */
  std::function<void()> &on_destroy();

  /** \brief make the popup take an explicit grab
      \param seat the wl_seat of the user event
      \param serial the serial of the user event

	This request makes the created popup take an explicit grab. An explicit
	grab will be dismissed when the user dismisses the popup, or when the
	client destroys the xdg_popup. This can be done by the user clicking
	outside the surface, using the keyboard, or even locking the screen
	through closing the lid or a timeout.

	If the compositor denies the grab, the popup will be immediately
	dismissed.

	This request must be used in response to some sort of user action like a
	button press, key press, or touch down event. The serial number of the
	event should be passed as 'serial'.

	The parent of a grabbing popup must either be an xdg_toplevel surface or
	another xdg_popup with an explicit grab. If the parent is another
	xdg_popup it means that the popups are nested, with this popup now being
	the topmost popup.

	Nested popups must be destroyed in the reverse order they were created
	in, e.g. the only popup you are allowed to destroy at all times is the
	topmost one.

	When compositors choose to dismiss a popup, they may dismiss every
	nested grabbing popup as well. When a compositor dismisses popups, it
	will follow the same dismissing order as required from the client.

	The parent of a grabbing popup must either be another xdg_popup with an
	active explicit grab, or an xdg_popup or xdg_toplevel, if there are no
	explicit grabs already taken.

	If the topmost grabbing popup is destroyed, the grab will be returned to
	the parent of the popup, if that parent previously had an explicit grab.

	If the parent is a grabbing popup which has already been dismissed, this
	popup will be immediately dismissed. If the parent is a popup that did
	not take an explicit grab, an error will be raised.

	During a popup grab, the client owning the grab will receive pointer
	and touch events for all their surfaces as normal (similar to an
	"owner-events" grab in X11 parlance), while the top most grabbing popup
	will always have keyboard focus.
      
  */
  std::function<void(seat_t, uint32_t)> &on_grab();

  /** \brief configure the popup surface
      \param x x position relative to parent surface window geometry
      \param y y position relative to parent surface window geometry
      \param width window geometry width
      \param height window geometry height

	This event asks the popup surface to configure itself given the
	configuration. The configured state should not be applied immediately.
	See xdg_surface.configure for details.

	The x and y arguments represent the position the popup was placed at
	given the xdg_positioner rule, relative to the upper left corner of the
	window geometry of the parent surface.
      
  */
  void configure(int32_t x, int32_t y, int32_t width, int32_t height, bool post = true);

  /** \brief Minimum protocol version required for the \ref configure function
  */
  static constexpr std::uint32_t configure_since_version = 1;

  /** \brief popup interaction is done

	The popup_done event is sent out when a popup is dismissed by the
	compositor. The client should destroy the xdg_popup object at this
	point.
      
  */
  void popup_done(bool post = true);

  /** \brief Minimum protocol version required for the \ref popup_done function
  */
  static constexpr std::uint32_t popup_done_since_version = 1;

  /** \brief Post error: tried to grab after being mapped
  */
  void post_invalid_grab(std::string const& msg);

};

using global_zxdg_popup_v6_t = global_t<zxdg_popup_v6_t>;

/** \brief 

  */
enum class zxdg_popup_v6_error : uint32_t
  {
  /** \brief tried to grab after being mapped */
  invalid_grab = 0
};


/** \brief context object for keyboard grab manager

      A global interface used for grabbing the keyboard.
    
*/
class zwp_xwayland_keyboard_grab_manager_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
    std::function<void(zwp_xwayland_keyboard_grab_v1_t, surface_t, seat_t)> grab_keyboard;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_xwayland_keyboard_grab_manager_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_xwayland_keyboard_grab_manager_v1_t>;
  friend class global_base_t;

public:
  zwp_xwayland_keyboard_grab_manager_v1_t() = default;
  zwp_xwayland_keyboard_grab_manager_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_xwayland_keyboard_grab_manager_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_xwayland_keyboard_grab_manager_v1*() const;

  /** \brief destroy the keyboard grab manager

	Destroy the keyboard grab manager.
      
  */
  std::function<void()> &on_destroy();

  /** \brief grab the keyboard to a surface
      \param id 
      \param surface surface to report keyboard events to
      \param seat the seat for which the keyboard should be grabbed

	The grab_keyboard request asks for a grab of the keyboard, forcing
	the keyboard focus for the given seat upon the given surface.

	The protocol provides no guarantee that the grab is ever satisfied,
	and does not require the compositor to send an error if the grab
	cannot ever be satisfied. It is thus possible to request a keyboard
	grab that will never be effective.

	The protocol:

	* does not guarantee that the grab itself is applied for a surface,
	  the grab request may be silently ignored by the compositor,
	* does not guarantee that any events are sent to this client even
	  if the grab is applied to a surface,
	* does not guarantee that events sent to this client are exhaustive,
	  a compositor may filter some events for its own consumption,
	* does not guarantee that events sent to this client are continuous,
	  a compositor may change and reroute keyboard events while the grab
	  is nominally active.
      
  */
  std::function<void(zwp_xwayland_keyboard_grab_v1_t, surface_t, seat_t)> &on_grab_keyboard();

};

using global_zwp_xwayland_keyboard_grab_manager_v1_t = global_t<zwp_xwayland_keyboard_grab_manager_v1_t>;


/** \brief interface for grabbing the keyboard

      A global interface used for grabbing the keyboard.
    
*/
class zwp_xwayland_keyboard_grab_v1_t : public resource_t
{
private:
  struct events_t : public resource_t::events_base_t
  {
    std::function<void()> destroy;
  };

  static int dispatcher(int opcode, const std::vector<wayland::detail::any>& args, const std::shared_ptr<resource_t::events_base_t>& e);

protected:
  static constexpr const wl_interface *interface = &wayland::server::detail::zwp_xwayland_keyboard_grab_v1_interface;
  static constexpr const unsigned int max_version = 1;

  friend class global_t<zwp_xwayland_keyboard_grab_v1_t>;
  friend class global_base_t;

public:
  zwp_xwayland_keyboard_grab_v1_t() = default;
  zwp_xwayland_keyboard_grab_v1_t(const client_t& client, uint32_t id, int version = 1);
  zwp_xwayland_keyboard_grab_v1_t(const resource_t &resource);

  static const std::string interface_name;

  operator zwp_xwayland_keyboard_grab_v1*() const;

  /** \brief destroy the grabbed keyboard object

	Destroy the grabbed keyboard object. If applicable, the compositor
	will ungrab the keyboard.
      
  */
  std::function<void()> &on_destroy();

};

using global_zwp_xwayland_keyboard_grab_v1_t = global_t<zwp_xwayland_keyboard_grab_v1_t>;



}
}
