shells (Re: [PATCH weston 4/5] Make use of new wl_cursors)

Pekka Paalanen ppaalanen at gmail.com
Thu Jul 26 14:03:37 PDT 2012


On Thu, 26 Jul 2012 12:37:01 -0700
Bill Spitzak <spitzak at gmail.com> wrote:

> >> What is the meaning of more than one shell? Or is there another reason 
> >> for the shell argument?
> > 
> > A shell does window management...
> 
> I think my question was misunderstood. What I meant was "What is the 
> meaning of more than one shell SIMULTANEOUSLY".

None.

> If a wayland instance can only use one shell at a time, there should be 
> no need for this shell argument or the shell_surface, as the only 
> correct value is implicitly known.

No, the argument is needed, see below.

You conveniently cut off the part, where I actually replied on why
the shell is an argument in the C API. I will try to explain it again
in more words.

> The existence of these arguments (or of shell_surface) implies that 
> wayland can simultaneously have more than one shell, which is the only 
> reason a client has to be able to specify it.

Well, you can bind to the same shell several times, getting several
wl_shell client side objects, but it will always be the same shell
in the server.

But, there are real reasons why the argument is needed, and this is not
it, see blow.

> It also is possible that the existence of shell_surface is only to 
> categorize the methods in the stream api. However in that case I think 
> it should be much easier to instantly transform between surface and 
> shell_surface (ie they are the same id) and the complex rules about 
> creation and deletion should not be needed.

That is not how the protocol or its bindings work. Adding special
cases (implicit object or duplicated id) is a road to eventual chaos.

Simultaneously there can be only one shell plugin in the server. If
there were more, they would fight each other, or simply not be
used, since the last one loaded would overwrite all the function
pointers. However, nothing prevents a shell from implementing
several different shell protocol interfaces. But all that is
irrelevant.

When you write object oriented code in C, and you call methods of an
object, the function must take a pointer to the object in question
as an argument. Otherwise the method's implementation has no knowledge
of which object instance is in question. That is why
wl_shell_get_shell_surface() function
takes a wl_shell as the first argument. It cannot be implicit,
because the struct wl_shell object is created dynamically by the
application code *if* it needs it at all. The wl_shell object also
does *not* have a constant id associated in the protocol, because
id numbers are client-specific and allocated as needed. The only
exception is the wl_display object, which is always id 1, because
it is an elegant solution to bootstrapping the protocol. That is,
how to have some "global functions" you can use to create all the
other protocol objects from.

If we added some special code in libwayland-client, so that the
shell would be implicit, we would make the code non-generic: it would
have a hardcoded assumption, that wl_shell is special. Special
cases are a root of evil, especially when we right now have all
code dealing with the protocol C API automatically generated.

If we were coding in C++, or some other object oriented language,
wl_shell would not be the first argument of get_shell_surface(),
because the language itself would implicitly provide the "this"
pointer to the object in question.

When the remote side parses the protocol messages, it needs to
know the object type first. That it can look up from the object id
the client wrote into the message header. So, it is mandatory to
pass in the id of the wl_shell object. Otherwise the message parser
cannot know which method the given opcode (method number) in the
header corresponds to. Opcodes are private to an interface. If they
weren't, we could not easily change one interface without breaking
everything.

A client cannot use an interface, unless it has bound to it. Binding
to an interface, which ever way you do it, creates an object whose
type corresponds to the interface. Whether this protocol level
object (i.e., it has an object id) corresponds to none, a singleton,
or an newly created C object in the server, is irrelevant from the
API point of view. On client side, this protocol object is
represented as a C object (an instance of some opaque struct type).
When you call a method of an interface, you call the method of
this C object. Therefore you must pass the object pointer as an
argument.


Thanks,
pq


More information about the wayland-devel mailing list