libwayland and Java

Pekka Paalanen ppaalanen at gmail.com
Fri Jan 4 02:26:06 PST 2013


On Fri, 28 Dec 2012 17:16:40 -0600
Jason Ekstrand <jason at jlekstrand.net> wrote:

> PQ et. al.,

Hi Jason

> I've finally found the time to sit down and draft up my proposal for how
> events and requests get handled to make it easier to write language
> bindings. As a word of disclaimer, I've tried to pick through the source
> code on connection.c and a few other places but my working knowledge of
> libwayland's code-base isn't perfect. I'm taking a few ideas here from the
> way some of the JNI interfaces work. My recommendation would be to add the
> following type definition in wayland-util.h:
> 
> union wl_argument {
>     int32_t i;
>     uint32_t u;
>     wl_fixed_t f;
>     const char * s;
>     struct wl_object * o;
>     uint32_t n;
>     struct wl_array * a;
>     int32_t h;
> };
> 
> We then add the following additional variants of wl_resource_post_event and
> wl_resource_queue_event:
> 
> void wl_resource_post_event_array(stuct wl_resource *resource,
>         uint32_t opcode, wl_argument *arguments);
> 
> void wl_resource_queue_event_array(stuct wl_resource *resource,
>         uint32_t opcode, wl_argument *arguments);
> 
> This allows for easier posting of events with arguments determined at
> runtime.  Right now I have to wrap wl_resource_post_event in a JNI native
> method for every event. This would allow me to do all of the event handling
> in Java except for one JNI native method that does all of the argument
> handling at runtime.
> 
> To handle requests, we make the following modifications to wl_object:
> 
> struct wl_object {
>     const struct wl_interface * interface;
>     void (* const * implementation)(struct wl_object *, uint32_t,
>             void *, void *, union wl_argument *);

One indirection too much in function pointer, perhaps?

>     void *implementation_data;
>     uint32_t id;
> };
> 
> and define:
> 
> void wl_object_c_client_implementation(struct wl_object * reciever,
>         uint32_t opcode, void * data, void * server_object,
>         union wl_argument *args);
> 
> void wl_object_c_server_implementation(struct wl_object * reciever,
>         uint32_t opcode, void * client, void * resource,
>         union wl_argument *args);
> 
> Then for declaring objects in C, you simply assign one of
> wl_object_c_client_implementation or wl_object_c_server_implementation (as
> appropriate) to the implementation field and the array of function pointers
> that we currently call "implementation" to the implementation_data field.
> The wl_object_c_implementation function then uses libffi to compile
> everything into a closure and calles the requested function just as before.
> Built into this is an assumption about the types of the void pointers and
> the assumption that, for server code, any wl_object pointers in args would
> refer to a wl_object inside a resource. This would allow me to replace the
> way that requests are called with something JNI-specific. Again, right now
> I have a separate function for each request that simply wraps a call to a
> variadic function called wl_jni_resource_call_request; I could get rid of
> this extra step.
> 
> This would have two major advantages for java (or any other language)
> bindings.  The first is that with these two modifications I can have all my
> auto-generated code in Java instead of having to also generate C wrappers
> for everything. This would also allow the language border to be much more
> "natural" and more reliable.  Second, we could break libffi out as an
> optional dependency. We would still use libffi on most platforms but for
> the android case it could probably be removed which would make building far
> simpler. I realize that this isn't quite as simple as it looks because
> we're using the libffi [de]marshaler to handle requests to the wl_display
> object. However, it wouldn't be too hard to write a custom marshaler for
> wl_display and not require libffi.

Alright, good explanation. No immediate comments spring to my mind. It's
up to the project lead.

> There is still the issue of comparing interfaces. PQ said something about
> the current implementation comparing pointers. Perhaps we could simply
> compare the interface name and version to determine if two interfaces are
> the same.

Right, and I just noticed we already had code to deal with some of
that, interface_equal() function:
http://cgit.freedesktop.org/wayland/wayland/tree/src/connection.c#n838
Introduced in commit 4f9cf6ec4465411076d4facf6ab67a272f5183d9.

That is probably the thing I had in mind, and I cannot find other uses
of interface comparisons, neither in Weston. A non-issue, then?

> That's what I have in mind. It probably needs to be tweaked but this should
> at least give a flavor of what I'm looking for.
> --Jason Ekstrand


Thanks,
pq


More information about the wayland-devel mailing list