C++11 wrapper generator for Wayland client-side protocols
C++ Python Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
sample
.gitignore
COPYING
README.md
wlcppgen.py

README.md

wlcppgen

C++11 wrapper generator for Wayland client-side protocols

Features

  • Pure C++11!
  • Extensively customizable
  • No external dependencies besides Python 3 to generate the wrapper
  • Also generates wrappers for extensions protocols, not just the Wayland core protocol
  • Does not depend on code generated by the Wayland scanner (specifically, declarations in wayland-client-protocol.h are not used)
  • All calls to the Wayland client API happen from a common base class proxy, which has to be written manually. This way you can easily write a custom proxy class that dlopens libwayland-client.so at runtime instead of linking against it. This not so easily possible with code generated by the Wayland scanner.
  • Everything that is callable can be used as an event handler: function pointers, member function pointers, bind expressions, function objects and lambda expressions.

Usage

wlcppgen [command] [options] [protocols]

Available commands:
  --generate                   Generate wrappers. This is the default command.
                               Requires at least one protocol.
  --help, -h                   Display this help.
  --list-classes               List the class names which would be generated from
                               the given protocols.
                               Requires at least one protocol.
  --list-interfaces            List interfaces in every protocol.
                               Requires at least one protocol.
  --version                    Display version.

Available options:
  --dst                        Output filename.
                               If missing or "-" is given then stdout will be used.
  --exclude                    Comma-separated list of interfaces to exclude. This is
                               especially useful for wl_display, because a manually
                               written wrapper is more useful.
  --extra-includes             Comma-separated list of files for which include
                               directives are generated by the "include.extra" hook.
  --header (=wlcpp.hpp)        Header filename which contains declarations of the
                               generated code.
                               Can be used for the "include.self" hook.
  --ignore-events              Do not generate code for events.
  --include-guard (=_WLCPP_)   Name of the include guard.
  --indent (=4)                Number of spaces or tabs to indent.
  --indent-tabs                Indent using tabs instead of spaces.
  --interface-prefix           Prefix for generated class names. This options applies
                               after stripping.
  --interface-strip (=wl_)     Comma-separated list of prefixes to srtip from
                               interface names to generate class names. Only the first
                               prefix found is stripped.
  --linewidth (=80)            Maximum linewidth. Currently not very useful, because
                               it is only respected for comments and indentation is not
                               taken into account.
  --macro-prefix (=WLCPP_)     Prefix for preprocessor macros.
  --namespace (=wlcpp)         The generated code is put into the specified namespace.
                               Can be empty or an arbitrary namespace (e.g. foo::bar).
  --only                       Comma-separated list of interfaces to generate wrappers
                               for. This option takes precedence over --exclude.
                               Specifying exactly one interface activates single
                               interface mode. See below.
  --proxy (=proxy)             Name of the proxy class.
  --qualify-std-namespace      Prefix std types with "std::". Should be specified
                               when generating the header.
  --src                        Source template filename.
                               If missing or "-" is given then stdin will be used.

Single interface mode:
  When exactly one interface is specified through "--only", single interface mode is
  implicitly enabled which changes wlcppgen's behavior:
   * The hook target "include.required_headers" is available.
     This hook target assumes all other classes have also been generated in single
     interface mode. It uses the option "--header" to deduce the respective header
     file names.
   * Special identifiers can be used for the options "--header" and "--include-guard":
     "%c" - Class name
     "%C" - Uppercase class name

wlcppgen comes with a small pre-generated sample here. See generate.sh on how that specific wrapper was generated. It's a good place to start.

The sample client does not do much except print information about global objects. Patches are welcome :-)

How things are mapped to C++

  • There is a common base class for all interfaces named proxy by default. The proxy class has to be written manually, but an example is provided here and here.
  • The auto-generated class for wl_display is not very useful since it does not include special wl_display functions declared in wayland-client.h. Instead, I suggest to use the one provided in the /sample directory or write your own.
  • proxy sets itself (this) as the user data of the wl_proxy objects. This is required for event dispatching. The downside is that setting user data is no longer available to clients. But since you can use member functions and bind expressions as event handlers, this is also not required anymore.
  • Request and event arguments that are can be null are passed as pointers. References or value types are used otherwise.
  • Destructor requests (usually called destroy or release in case of wl_{pointer,keyboard,touch}) are not exposed directly to clients but implemented in a protected destroy member function which is called from the actual destructor and the move assignment operator.
  • Requests that return a new_id but do not specify the interface are implemented as template member functions. To the best of my knowledge wl_registry::bind is the only such request.
  • Setting custom dispatchers through wl_proxy_add_dispatcher is not possible.

Installation

There is not much to install. Just copy wlcppgen.py over to /usr/bin and you're done. It's probably best if you also strip the .py extension and just name it wlcppgen.

It is important to note that the generated code is not meant to be installed system-wide. You should compile it directly into your client application.

License

wlcppgen is distributed under the ISC license. See COPYING.

Please note that some code under /sample is auto-generated from the Wayland core protocol specification which is copyrighted by Kristian Høgsberg and others.