https://github.com/vector-of-bool/wlxx
Wayland Client C++ Bindings
https://github.com/vector-of-bool/wlxx
bindings cpp library wayland
Last synced: about 1 year ago
JSON representation
Wayland Client C++ Bindings
- Host: GitHub
- URL: https://github.com/vector-of-bool/wlxx
- Owner: vector-of-bool
- Created: 2017-09-04T22:28:11.000Z (almost 9 years ago)
- Default Branch: develop
- Last Pushed: 2018-02-20T05:21:11.000Z (over 8 years ago)
- Last Synced: 2025-03-25T01:20:36.357Z (over 1 year ago)
- Topics: bindings, cpp, library, wayland
- Language: Python
- Size: 43 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# IMPORTANT:
This project is just a little experiment I threw together in a few hours,
and hasn't been updated or given any proper TLC for several months.
For a library with the same design goals but proper maintainence and
support, look at [waylandpp](https://github.com/NilsBrause/waylandpp).
**Don't use this for anything important!**
# Wayland Client C++ Bindings
This library provides modern C++14 bindings to libwayland-client. These
bindings are *minimal* and provide little additional niceties over what is
already provided by the Wayland protocol specification. The following
C++-isms are provided by the library:
- RAII for all protocol types. (All types are move-only).
- Type-safety for all protocol types
- Error checking via exceptions or `std::error_code` output arguments for all
protocol requests (methods). For every method, there is an overload that is
`noexcept` and takes a `std::error_code&` as the final parameter, and another
that will throw `std::system_error` upon error.
- `enum class` scoped to their parent type for Wayland enums.
The following features are **NOT** present in the library:
- Shared memory facilities. You must bring your own shared memory library
(like Boost.Interprocess).
- Thread-safety of event dispatching (It's up to you to dispatch events
properly).
- Drawing and rendering. Bring your own renderer.
- Additional platform GUI abstractions. It's all the bare bones.
## Show Me the Code!
Using wl++ is simple:
```c++
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// We'll use Boost.Interprocess for shared memory
namespace ipc = boost::interprocess;
int main() {
// Connect to the Wayland display server
auto disp = wl::display::connect();
// Get the object registry
auto reg = disp.get_registry();
// The server will now pipe us some objects, which we'll need to store to continue
wl::compositor comp{nullptr}; // Null objects must be explicitly null-initialized
wl::shell shell{nullptr};
wl::shm shm{nullptr};
reg.on_global([&](auto id, std::string interface, int version) {
// Switch on the interface the server sent us
std::cout << "New " << interface << "@" << id << " from registry\n";
if (interface == wl::compositor::interface_name) {
comp = reg.bind(id, version);
} else if (interface == wl::shell::interface_name) {
shell = reg.bind(id, version);
} else if (interface == wl::shm::interface_name) {
shm = reg.bind(id, version);
}
});
// Pump events (this calls the on_global handler above)
disp.roundtrip();
// Create our shared memory
struct shm_remover_t {
shm_remover_t() {
ipc::shared_memory_object::remove("wlxx-example");
}
~shm_remover_t() {
ipc::shared_memory_object::remove("wlxx-example");
}
} _shm_remover;
ipc::shared_memory_object shared_memory{ipc::create_only, "wlxx-example", ipc::read_write};
// We'll use 8-bit color depth with ARGB layout
struct pixel {
// Components are in reverse order, because endian?
std::uint8_t b;
std::uint8_t g;
std::uint8_t r;
std::uint8_t a;
};
const auto width = 400;
const auto height = 300;
const auto n_pixels = width * height;
const auto shared_size = n_pixels * sizeof(pixel);
shared_memory.truncate(shared_size);
// Tell Wayland about our shared memory object
auto shm_pool = shm.create_pool(shared_memory.get_mapping_handle().handle, shared_size);
// Create a buffer. This doesn't allocate anything, it just tells wayland
// about memory regions that we intend to use, and how to treat them
auto draw_buffer
= shm_pool
.create_buffer(0, // Offset in the shared memory region. We start at the beginning
width,
height,
width * sizeof(pixel), // The "stride." This is the size (in bytes) of
// a row of pixels
wl::shm::format::argb8888 // This is the draw format we want
);
// Map the memory into our address space so we can get writing
ipc::mapped_region shared_region{shared_memory, ipc::read_write};
// Fill our draw with green pixels
pixel green;
green.a = 255;
green.r = 0;
green.g = 200;
green.b = 0;
const auto pixel_out = static_cast(shared_region.get_address());
std::fill(pixel_out, pixel_out + n_pixels, green);
// Ask the compositor for a new surface (usually, a window)
auto surface = comp.create_surface();
// shell_surface is an abstraction over the desktop shell
auto shell_surface = shell.get_shell_surface(surface);
// It's a root window
shell_surface.set_toplevel();
// Attach the draw buffer to the top left corner (0, 0) of the surface
surface.attach(draw_buffer, 0, 0);
// Swap the double-buffer, and show our surface!
surface.commit();
disp.flush();
std::this_thread::sleep_for(std::chrono::seconds(10));
return 0;
}
```
## Documentation?
Since wl++ is simply a very small wrapper of the Wayland protocol, the [protocol documenation](https://wayland.freedesktop.org/docs/html/apa.html) is the best place to understand what APIs are available in wl++. There are only a few small differences:
- Calling any `destroy()` method is unnecessary in the face of destructors.
- `wl::registry::bind` does not return `void*`. It is a method template that
returns an instance of the requested type.
### Events
For each type of event on an object, a method `on_` is present on
the class, and can be used to set the event handler. The method takes a
callback object that will be called with the event parameters when the event
fires. **NOTE** that wl++ provides no event loop. It's up to you to dispatch
events by calling the proper methods on the `wl::display` instance.