You need a wayland compositor library to create a wayland server. Wayland is a
protocol, itself, cannot do much, long time ago I used to think the server-side
wl_resource represents some structure you can operate on, well it turned out
all you do with it is handling messages between client and server. All the logic
you need to implement yourself.
There were a few attempts to wayland compositing library created. The first sucessful one is wlc. I think its existence is that weston (the twin of the wayland project, now maintained by Pekka Paalanen). was a monolith application for a long time. Weston looks pretty and quite fast and beautiful but not very useful to anyone else. The developers maybe realized that they want to get more people to use weston, so they managed to strip libweston out of weston itself. It was a good attempt, although I doubt their true intention was to creating a reusable compositing library. Nonetheless, to some extent, it helped the birth of the third library by Drew Devault, the wlroots.
Over this month, I am trying to migrate from libweston. Over these years, I slowly discovered that libweston has its hidden flaws that need to be patched, I tried a few times to send Merge requests, now I lost my faith and gave up on patching libweston. Well, it is hard to argue on a project you do not maintain. The feature you thought would be important may not be the same for others. The target platform, is the wlroots. This time however, I learned from my previous mistake, a open source project is like a person, you cannot expect it to be something it has not been yet. This time, I merely use wlroots as a thin layer for hardware abstraction(if there is any good alternative I would ditch wlroots for sure). Libliftoff looks like a good candidate, depends on if it gets mature. Maybe in the end I would have to write one myself.
A brief view
Anyway, the purpose today is comparing libweston and wlroots. Though Drew Devault claimed wlroots is a much better choice, I see them similar in many ways, in implementing many protocols.
|input modifier||grab system||grab system|
Though many types in libweston you can find correspondence in wlroots,
some of the implementation are also similar, eg, data-device, but you can also
find the significant difference. In libweston, you have the
weston_compositor as a middle layer, it does all the heavily lifting, as a
user, you would add decorations on top of it, for example, you could add some
callbacks on output creation. On the land of wlroots, you will be heavily
wl_signal. The library notifies you when to do something , but to do
what and how to do is totally up-to-you. As good as it sounds, wlroots also
has its limitations, by design, you are almost forced to use none-or-all of its
wlr_compositor depends on
wlr_data_device depends on
wlr_seat, the list goes on. Some of the dependencies to me were not necessary,
but again, if I propose to change it, highly likely would be rejected. Also, by
its design, wlroots implements similar protocols in different types, eg,
wl_shell. You would have to deal with the
interface one-by-one, In libweston, they are nicely implemented together and it
libweston_desktop API to you.
Now let us have a run using the two library, to get a more concrete idea.
A quick run into libweston.
You start by creating
wl_display and creating
first(it self already does quite a few things, implement many protocols). Before
waking the compositor, you would want to setting some listeners and signals on
seat, output creations. It is also the good time for adding the callbacks
Libweston comes with a few backend, like
fbdev_backend, those are the backends implements
weston_seat. Choosing a backend before waking up compositor is necessary,
otherwise you would not process any events.
Now after After the waking of
can have very few additional setups on the compositor.
xkb_rules are already
fixed, you cannot change the modes, or scale of enabled output. But you can
still create some
wl_globals for your needs.
Finally, calling the
wl_display_run would start processing the event queue.
A quick run on the wlroots.
You start again, by creating
wl_display, wlroots does not have a
compositor object, instead, you work with
wlr_backend, it abstracts away the
hardware events and rendering callbacks. As metioned before, wlroots heavily
relies on signals,
wlr_backend is a perfect example. By adding listeners to
new_output. You can handle objects like
wlr_input_device. Each of those objects has their own events,
wlr_input_deivce.events is used for input handling. You additionally
creating objects like
wlr_seat(which is a protocol implementation) for
forwarding input events to your clients. This is a critical point actually, if
you decide to go with wlroots objects, from this point you will need to go
all the way. If you decide to implement your own wayland interfaces, you can
forget all the types like
Back on the topic, in creating the
wlr_backend, you also would want to create
your own renderer or not, wlroots comes with a very renderer. After all
those objects created, press the button
wlr_backend_start for launching the
compositor, a bit similar to
weston_compositor_wake right? If nothing goes
wrong, you would see a window by now.
There are many other details needed to filled, since wlroots is a modular
library, every protocol you want to support needs to be added explicitly, you
probably want a
xdg_shell for example.
In the end, call
wl_display_run to start the event queue.
I hope this article would be useful for getting an idea about wayland compositor librarys. There are some design I preferred in libweston but in general I would prefer the modular design of wlroots, it looks much less intimidating. You can understand a type at a time, Where in libweston, every c file in libweston is like a few thousands lines long, understanding the project and adding modification is difficult, though it is a more mature project.