summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnkit Nautiyal <ankit.k.nautiyal@intel.com>2019-04-03 19:21:58 +0530
committerAnkit Nautiyal <ankit.k.nautiyal@intel.com>2019-07-05 14:13:24 +0530
commitf74c35b1f4a62543e559de3455c60c82dc468ade (patch)
treed5cb03c5129a6bea4a535edcd758fb7f344b534e
parent5cfe03c8630074a9fac3646dc774ac668c0206e9 (diff)
downloadweston-f74c35b1f4a62543e559de3455c60c82dc468ade.tar.gz
libweston: Notify client for change in content-protection status
The change in an output's content-protection may trigger a change in the surface's content-protection status, and inturn the content-protection available for the client. This patch recomputes the content-protection level for a surface, in case there is a change in content-protection level of an output, showing the surface. In case of a change in the surface's content-protection, the client associated with that surface is notified. Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
-rw-r--r--include/libweston/libweston.h1
-rw-r--r--libweston/compositor.c71
-rw-r--r--libweston/content-protection.c1
3 files changed, 72 insertions, 1 deletions
diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h
index 04a17918..7d3307e1 100644
--- a/include/libweston/libweston.h
+++ b/include/libweston/libweston.h
@@ -1630,6 +1630,7 @@ struct content_protection {
struct wl_listener destroy_listener;
struct weston_log_scope *debug;
struct wl_list protected_list;
+ struct wl_event_source *surface_protection_update;
};
diff --git a/libweston/compositor.c b/libweston/compositor.c
index fc11ae5c..d417d7ac 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -1032,6 +1032,47 @@ weston_surface_send_enter_leave(struct weston_surface *surface,
}
}
+static void
+weston_surface_compute_protection(struct protected_surface *psurface)
+{
+ enum weston_hdcp_protection min_protection;
+ bool min_protection_valid = false;
+ struct weston_surface *surface = psurface->surface;
+ struct weston_output *output;
+
+ wl_list_for_each(output, &surface->compositor->output_list, link)
+ if (surface->output_mask & (1u << output->id)) {
+ if (!min_protection_valid) {
+ min_protection = output->current_protection;
+ min_protection_valid = true;
+ }
+ if (output->current_protection < min_protection)
+ min_protection = output->current_protection;
+ }
+ if (!min_protection_valid)
+ min_protection = WESTON_HDCP_DISABLE;
+
+ surface->current_protection = min_protection;
+ weston_protected_surface_send_event(psurface,
+ surface->current_protection);
+}
+
+static void
+notify_surface_protection_change(void *data)
+{
+ struct weston_compositor *compositor = data;
+ struct content_protection *cp;
+ struct protected_surface *psurface;
+
+ cp = compositor->content_protection;
+ cp->surface_protection_update = NULL;
+
+ /* Notify the clients, whose surfaces are changed */
+ wl_list_for_each(psurface, &cp->protected_list, link)
+ if (psurface && psurface->surface)
+ weston_surface_compute_protection(psurface);
+}
+
/**
* \param es The surface
* \param mask The new set of outputs for the surface
@@ -1050,6 +1091,8 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
uint32_t output_bit;
struct weston_output *output;
struct weston_head *head;
+ struct content_protection *cp;
+ struct wl_event_loop *loop;
es->output_mask = mask;
if (es->resource == NULL)
@@ -1068,6 +1111,17 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
output_bit & left);
}
}
+ /*
+ * Change in surfaces' output mask might trigger a change in its
+ * protection.
+ */
+ loop = wl_display_get_event_loop(es->compositor->wl_display);
+ cp = es->compositor->content_protection;
+ if (!cp || cp->surface_protection_update)
+ return;
+ cp->surface_protection_update = wl_event_loop_add_idle(loop,
+ notify_surface_protection_change,
+ es->compositor);
}
static void
@@ -5338,6 +5392,11 @@ weston_output_compute_protection(struct weston_output *output)
struct weston_head *head;
enum weston_hdcp_protection op_protection;
bool op_protection_valid = false;
+ struct weston_compositor *wc = output->compositor;
+ struct content_protection *cp = wc->content_protection;
+
+ if (!cp)
+ return;
wl_list_for_each(head, &output->head_list, output_link) {
if (!op_protection_valid) {
@@ -5351,8 +5410,18 @@ weston_output_compute_protection(struct weston_output *output)
if (!op_protection_valid)
op_protection = WESTON_HDCP_DISABLE;
- if (output->current_protection != op_protection)
+ if (output->current_protection != op_protection) {
+ struct wl_event_loop *loop;
+
output->current_protection = op_protection;
+ weston_output_damage(output);
+ if (cp->surface_protection_update)
+ return;
+ loop = wl_display_get_event_loop(wc->wl_display);
+ cp->surface_protection_update = wl_event_loop_add_idle(loop,
+ notify_surface_protection_change,
+ wc);
+ }
}
WL_EXPORT void
diff --git a/libweston/content-protection.c b/libweston/content-protection.c
index 72865a51..689a2ec8 100644
--- a/libweston/content-protection.c
+++ b/libweston/content-protection.c
@@ -189,6 +189,7 @@ cp_destroy_listener(struct wl_listener *listener, void *data)
wl_list_remove(&cp->protected_list);
weston_compositor_log_scope_destroy(cp->debug);
cp->debug = NULL;
+ cp->surface_protection_update = NULL;
free(cp);
}