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