Basic API usage

Pekka Paalanen ppaalanen at gmail.com
Thu Sep 10 08:16:42 UTC 2020


On Wed, 9 Sep 2020 17:44:59 +0200
Jan Bruns <code at abnuto.de> wrote:

> Ok. I now have an even earlier point of missing knowledge than I expected:
> 
> Why does the generated version of wayland-client-protocol.h reference a 
> server object called "wl_registry_interface"?

These interface structures are used both server and client side. The
core of libwayland needs to know the message signatures for it to be
able to marshall them. As we want people to be able to use
new extensions (XML files) without needing to rebuild libwayland to
match, the signatures must be provided to libwayland.

Being able to use custom XML files at will has been very important in
letting Wayland succeed, as people can experiment on their own without
needing to upstream their extension to libwayland - they just need their
extensions with their own compositor and clients.

With wayland-scanner, a client side project needs to generate and use
both client-header and private-code, and a server side project needs to
generate and use both server-header and private-code.

Again wayland.xml is special: libwayland-client and libwayland-server both
export these "code" symbols (with identical content, so it doesn't
matter which one actually gets used), but for any other XML file you
need to generate the code yourself.

This stems from a very early implementation design of Wayland, and
there might have been a better design to be chosen, but this is what we
have. I suppose the idea is to not need to duplicate the message
signature data too much.

> It makes use of it in
> 
> 
> extern const struct wl_interface wl_registry_interface;
> 
> 
> static inline struct wl_registry *
> wl_display_get_registry(struct wl_display *wl_display)
> {
>      struct wl_proxy *registry;
> 
>      registry = wl_proxy_marshal_constructor((struct wl_proxy *) wl_display,
>               WL_DISPLAY_GET_REGISTRY, &wl_registry_interface, NULL);
> 
>      return (struct wl_registry *) registry;
> }
> 
> 
> 
> Doesn't wl_proxy_marshal_constructor normally allocate client-side 
> "objects, proxies" for new-id args?

Correct.

struct wl_proxy is the client-side representation of a protocol object,
and the C bindings cast it to interface-specific types like struct
wl_surface * to have a little bit of type-safety in the client-side C
bindings. There is no struct wl_surface actually defined anywhere.

struct wl_resource is the server-side representation or a protocol
object. The C bindings do not generate type-safe wrappers for
server-side like they do for client-side.

Unfortunately some same type names are used to reference totally
different things: server-side wl_display is nothing like client-side
wl_display. struct wl_buffer used to have a server-side definition
which is now deprecated, and there is also an internal struct wl_buffer
which is a completely different thing. The client side "fake" type
struct wl_buffer * exists too and is used for type-safety.

Why such a mess? Hysterical raisins, as someone once typoed.

> An attempt to do the very same thing (import the named memory block by 
> means of linker, and passing an adress to that) from within simple 
> typeless testing code made wl_proxy_marshal_constructor return NULL 
> (instead of crashing). Maybe some detail I have done wrong, but I don't 
> understand what's going on here anyway.

I don't think I can guess what happened there.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20200910/fbc8d170/attachment.sig>


More information about the wayland-devel mailing list