diff options
author | Philipp Kerling <pkerling@casix.org> | 2017-08-16 12:37:27 +0200 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2017-08-17 11:06:29 +0800 |
commit | 62affbb44b771931a8895fc7428df23afb888750 (patch) | |
tree | 35519f4e31fe1470d8760374b0c0dde8a5720f60 | |
parent | 324a725e5068a538e2446b0b73cccb3c119f3d8b (diff) | |
download | libva-62affbb44b771931a8895fc7428df23afb888750.tar.gz |
wayland: Implement registry remove handler
Wayland event handlers are never optional. libwayland-client will abort
the program if events for unbound handlers are to be dispatched.
Although the event queue is only dispatched a few times during
initialization for getting the wl_drm global and authenticating the DRM
device, in rare circumstances it can happen that another global such as
a wl_output - or even wl_drm itself - is removed during that time, which
would crash the program. Implement the handler to fix this.
Fixes: #99
Signed-off-by: Philipp Kerling <pkerling@casix.org>
-rw-r--r-- | va/wayland/va_wayland_drm.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/va/wayland/va_wayland_drm.c b/va/wayland/va_wayland_drm.c index a4d3ebb..552f243 100644 --- a/va/wayland/va_wayland_drm.c +++ b/va/wayland/va_wayland_drm.c @@ -41,6 +41,7 @@ typedef struct va_wayland_drm_context { struct va_wayland_context base; struct wl_event_queue *queue; struct wl_drm *drm; + uint32_t drm_name; struct wl_registry *registry; unsigned int is_authenticated : 1; } VADisplayContextWaylandDRM; @@ -148,7 +149,7 @@ static void registry_handle_global( void *data, struct wl_registry *registry, - uint32_t id, + uint32_t name, const char *interface, uint32_t version ) @@ -159,15 +160,31 @@ registry_handle_global( /* bind to at most version 2, but also support version 1 if * compositor does not have v2 */ + wl_drm_ctx->drm_name = name; wl_drm_ctx->drm = - wl_registry_bind(wl_drm_ctx->registry, id, &wl_drm_interface, + wl_registry_bind(wl_drm_ctx->registry, name, &wl_drm_interface, (version < 2) ? version : 2); } } +static void +registry_handle_global_remove( + void *data, + struct wl_registry *registry, + uint32_t name +) +{ + struct va_wayland_drm_context *wl_drm_ctx = data; + + if (wl_drm_ctx->drm && name == wl_drm_ctx->drm_name) { + wl_drm_destroy(wl_drm_ctx->drm); + wl_drm_ctx->drm = NULL; + } +} + static const struct wl_registry_listener registry_listener = { registry_handle_global, - NULL, + registry_handle_global_remove }; static bool |