On Thu, 16 Oct 2014 09:46:39 +0300 Pekka Paalanen <ppaala...@gmail.com> wrote:
> On Wed, 15 Oct 2014 22:44:25 +0400 > Dmitry Cherkassov <dcherkas...@gmail.com> wrote: > > > Hi list! > > > > The definition of wl_display_interface symbol can come from > > libwayland-server.so or libwayland-client.so. > > > > There is a code in closed source EGL implementation that does > > interfaces comparison via pointers, yielding negative results when > > addresses are different (one address is saved by QtWayland, the other > > one is from &wl_display_interface in EGL source code). > > > > Is there a smarter way to compare wl_display_interface's? > > > > There is this function: > > > > wl_interface_equal(const struct wl_interface *a, const struct wl_interface > > *b) > > { > > return a == b || strcmp(a->name, b->name) == 0; > > } > > > > But as you can see it's not safe to use it alone because in case of > > bad pointer we will get undefined results. > > > > Currently struct wl_interface is the following: > > struct wl_interface { > > const char *name; > > int version; > > int method_count; > > const struct wl_message *methods; > > int event_count; > > const struct wl_message *events; > > }; > > > > Since there is no magic field at the beginning it is not possible to > > see whether a pointer points to the valid wl_interface structure. > > > > So my question is: how can we compare wl_interfaces in more clever and > > safer way? > > Hmm, why would you ever have a bad pointer? > > Bad pointers in general tend to cause crashes and stuff, so you > shouldn't be having a bad one in the first place. > > What is the background for your question/problem? Ok, I suppose this was discussed in IRC last night: the actual problem behind the question is how to detect whether the void pointer (EGLNativeDisplayType) given to eglCreateDisplay is actually a wl_display. That's tough. A couple of hacks come to mind. bool _eglNativePlatformDetectWayland(void *nativeDisplay) { void *f; if (!dereferencable(nativeDisplay)) return false; f = *(void **)nativeDisplay; The first is to dlopen both libwayland-client and libwayland-server in turn with RTLD_NOLOAD | RTLD_LOCAL, and fetching the wl_display_interface symbol from each, comparing those to 'f'. If either matches, return true. Another would be to check if 'f' is dereferencable (and not equal to the default wl_display_interface), and check if (char *)f starts with "wl_d". If yes, do a full string comparison with "wl_display". It's not reliable, but maybe works enough. The proper solution is for apps to use EGL_KHR_platform_wayland to explicitly say the pointer is a wl_display. That of course doesn't work on old apps, so you might implement a workaround through environment like Mesa does: EGL_PLATFORM=wayland bypasses all autodetection and assumes it is a wl_display. In any case, EGL really should implement EGL_KHR_platform_wayland so we have a chance to get rid of the inherently unreliable autodetect. And we should start using that in our demo apps... If we consider autodetecting client wl_display pointers worth to solve properly, we should probably add a function for that in libwayland-client.so. However, implementing that portably might be difficult. Thanks, pq _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel