Wayland and Weston 1.0.0 have been released!
Thanks and congrats to everybody involved for making this happen.
We're entering a new, exciting and somewhat scary phase for Wayland.
As of this 1.0.0 release, we're changing the development model and
committing to the the protocol and client side API we have now.
As I've said before, 1.0 doesn't mean we're done or that the protocol
can't move forward. What it means, is that we're confident that the
protocol we have now covers the basic features and that we can build
whatever new functionality we need with and on top of 1.0.
Tarballs and tags are out there, in git and from
http://wayland.freedesktop.org/releases:
c8f39b099d9a5c6c5609046a31ef371655eb2c05 wayland-1.0.0.tar.xz
1f521a4f7760df73e1d1d8a6791d1c7bf536584e wayland 1.0.0 tag
b179dff28403d05e2a4f1a1846772bb83b36b51a weston-1.0.0.tar.xz
42470cfc492d03e967ae515d298b1d4712de9a58 weston 1.0.0 tag
I think we will do a 1.0.1 release within a few weeks, mainly to
improve documentation, but other than that there's no roadmap for
further releases at this point.
Protocol Versioning
As we're now starting to use the versioning mechanism, let me just
outline how it works:
- The interface versioning mechanims in the protocol is modelled
after how the X extension versioning works. That's one of the
things that have worked well in X and the Wayland protocol has that
built in. The core idea is that we never break backwards
compatibility for interfaces. We only add new requests and events,
we never remove or modify old ones. The wl_registry object will
initially advertise all globals and their interfaces and versions.
When binding a global object, the client tells the server which
version it understands. This version may be lower than what the
server supports, in which case the server will not send out more
recent events.
- As well as adding interfaces over time, we can also deprecate and
remove interfaces. Clients discover the supported interfaces
dynamically and they have the means to fall back gracefully, in
case an extension isn't available. We'll only remove interfaces
after a long deprecation phase and when we have a replacement.
- Compositors may expose private protocol to be used by components
tied to and released with the compositor or released separately.
Either way, the API stability of these interfaces is policy of that
compositor and outside the scope of the core Wayland protocol.
Versioning convention for releases
- The protocol and generated code as defined by wayland.xml and the
client API as defined in wayland-client.h will remain stable for
all 1.x.x releases. We may add protocol and API in the 1.x.x
series, but any client side application that compiles and links
against libwayland-client.so 1.0.0 will continue to do so for all
1.x.x releases.
- The server side generated code and API as defined in
wayland-server.h will be stable through 1.0.x releases. On the
master branch we may move code back and forth between weston and
wayland or break API in other ways. Eventually, we'll make a 1.1.0
release, and keep the server side API stable for the 1.1.x series,
but there are no concrete plans at this point.
- Weston will maintain internal module API and ABI stability for the
1.0.x releases. We won't do any new development on this 1.0 branch
and we'll make releases when there's a need for one (if anybody
needs a release, let the list know). Feature work continues on the
master branch and we make no guarantees about the module interface
there.
Even though we maintain the module API/ABI in 1.0.x, there is
currently no official mechanism for developing out-of-tree modules.
The best approach is to just copy src/compositor.h into the
out-of-tree module source and develop against that.
Changes since 0.95.0 and 0.99.0
Since 0.95.0, we've fixed a lot of bugs and added much documentation
and we managed to only make few user visible changes. But just before
0.99.0, a few changes landed that broke the client side API. Most of
these changes are well documented in the code or in the protocol
definition, but I'll just outline them here:
- Changes to make the API thread safe. These are by far the most
invasive changes and affect the global mechanism and mainloop
integration. These changes removed callbacks from the core API and
introduced the wl_event_queue as a mechanism to control when and
where event callbacks are invoked. The new event loop API is
simpler than what we had before. For typical toolkit integration,
follow these steps:
1) Get the socket fd using wl_display_get_fd()
2) Add the fd to mainloop and poll the fd for readable by default
3) When the fd is readable, call wl_display_dispatch() to invoke
the event callbacks
4) Before going back to sleep, call wl_display_dispatch_pending()
and the wl_display_flush() to write buffered requests to the
server. If wl_display_flush() returns -1 with errno set to
EAGAIN, poll the fd for writable as well and call
wl_display_flush() when the fd becomes writable again.
Note that all of these calls may return -1 in case of error, either
from the call or if the display is in an error state.
The global listener mechanism has been replaced by a new
wl_registry interface. Some of the convenience API
(wl_display_get_global) had to go and on the whole the new
mechanism is a little more cumbersome to use. But the change
itself is pretty mechanical; the bind request and global and
global_remove events moved into wl_registry, and to listen for
globals just call wl_display.get_registry and add a listener to
that object.
- Atomic surface update mechanism. The exact semantics of how and
when changes to surface took effect were a little fuzzy. In
practice, everything that fit into a protocol buffer (ie most
things you'd do to a surface in a frame) would be applied
atomically due to how we process incoming requests in the server.
It just wasn't clearly specified or fool-proof in the face of
protocol buffer overflows or flushes and could cause rendering
artifacts. We now have the wl_surface.commit request, which must
be used to commit the pending changes to a surface. Any state that
depends on surface size or content must be done before committing
and when the server receives the commit request it will apply all
the batched up changes. If using EGL, eglSwapBuffers() will attach
a new buffer and send the commit request.
- Better and more consistent error checking. We had a number of
cases where we didn't handle out-of-memory and in cases of any
socket errors we just called abort(). We now handle all cases and
in case of error, the core entry points will return -1 and set
errno. For the protocol stubs, any errors will set an error state
in the wl_display object. Core entry points will then return -1,
or the state be inspected with wl_display_get_error().
- Remove un-namespaced ARRAY_LENGTH and container_of from public API.
A long time bad habit that we had to break. Hopefully most
applications and toolkits weren't using these macros. Either way,
toolkits provide similar functionality and worst case they can just
be copy-and-pasted.
Kristian