I found a solution, but my offer to send a pull request adding wl_object_get_class() and wl_object_get_id() still stands. Let me know!
To recap, my key question was: "The wl_protocol_logger API exposes a wl_object struct. How can I get the object class and ID from a wl_object?" To answer my own question: wl_object is actually declared here, behind an #ifndef: https://gitlab.freedesktop.org/wayland/wayland/-/blob/69633202180acce9d0d5ab4037d80291c71b2307/src/wayland-server.h#L58 The declaration is deprecated, though. I'm using it anyway for now, but I think accessor functions would be better so that I can treat wl_object as opaque. I'm happy to contribute if desired. Best regards, Chloe On Tue, Apr 16, 2024 at 10:56 AM Chloe Pelling <cpell...@google.com> wrote: > Hi, > > I'm attempting to use the wl_protocol_logger API to replicate the > functionality of WAYLAND_DEBUG=1 in my project, but logging to > https://perfetto.dev/ rather than stderr. I'm having some trouble > decoding message arguments of type object, since `wl_object` is an > opaque struct and there doesn't appear to be a "blessed" way to > interrogate it. In particular, there's no API to access > `wl_object::id`. > > Am I missing something? Would a patch adding wl_object_get_id() and > wl_object_get_class() functions be welcome? > > Here's what I've figured out so far: > > * Decoding the arguments requires inspecting the wl_argument unions in > `wl_protocol_logger_message::arguments`, according to the type > indications in `wl_protocol_logger_message::message->signature`. > > * Object arguments are denoted by "o" in the signature, indicating we > should examine `wl_argument::o` of type wl_object. > > * wl_object is an opaque struct, and there are no > wl_object_get_class() or wl_object_get_id() functions. > > * I can work around the lack of wl_object_get_class() by inspecting > wl_protocol_logger_message::message->types[i] for argument > wl_protocol_logger_message::arguments[i]. However, no such workaround > exists to retrieve the wl_object's id. > > * https://github.com/KDAB/GammaRay works around this problem by > casting wl_argument::o to wl_resource* and using > wl_resource_get_class() and wl_resource_get_id(). > > * This works because wl_resource's first member is wl_object, and > wl_resource_get_class() and wl_resource_get_id() are implemented only > by accessing that first member. > * While comments in wl_resource indicate that the struct layout > cannot be changed. It's unclear if that will be true forever. > * There is no guarantee that wl_resource_get_class() and > wl_resource_get_id() won't start accessing members of wl_resource > other than `object`. If they did, this technique could cause invalid > memory access due to overflowing the size of wl_object. > > I believe these are my current options: > > A) Cast wl_object* to wl_resource* like GammaRay does. I'm > uncomfortable with this, for the reasons above. > > B) Copy the definition of `struct wl_object` from wayland-private.h > into my project and access `id` directly. This might be safer than (A) > in practice, but I still don't like it. > > C) Submit a patch adding wl_object_get_class() and wl_object_get_id() > accessor functions. > > Have I missed something? Any advice would be helpful. > > Best regards, > Chloe >