[weston,v6,3/6] compositor: Add public interface support for client-requested idle inhibition

Submitted by Bryce Harrington on Sept. 9, 2016, 2:31 a.m.

Details

Message ID 1473388304-13231-4-git-send-email-bryce@osg.samsung.com
State New
Headers show
Series "Implement screensaver/idle inhibition" ( rev: 5 4 ) in Wayland

Not browsing as part of any series.

Commit Message

Bryce Harrington Sept. 9, 2016, 2:31 a.m.
This API allows clients to create an idle manager that can be used to
create per-surface inhibitor objects.  These direct the compositor to
not idle off the output that the surface is displayed on (i.e. don't
blank the surface's screen or show a screensaver).  When the inhibitor
object is destroyed, the inhibition request is automatically dropped and
a signal fired in libweston; this is used to communicate to the shell
that it should resume any idle behaviors (fade out animations, etc.)
and treat the output as idled.

If the client destroys the manager, the individual inhibitors will
remain active until destroyed.  The protocol spec does not define what
should happen in this situation, so this behavior may be altered once it
has been clarified.

Signed-off-by: Bryce Harrington <bryce@osg.samsung.com>
---
 Makefile.am            |   4 +-
 libweston/compositor.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++
 libweston/compositor.h |   9 +++--
 3 files changed, 111 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/Makefile.am b/Makefile.am
index 1e63a58..6241fa0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -176,7 +176,9 @@  nodist_libweston_@LIBWESTON_MAJOR@_la_SOURCES =				\
 	protocol/relative-pointer-unstable-v1-protocol.c		\
 	protocol/relative-pointer-unstable-v1-server-protocol.h		\
 	protocol/pointer-constraints-unstable-v1-protocol.c		\
-	protocol/pointer-constraints-unstable-v1-server-protocol.h
+	protocol/pointer-constraints-unstable-v1-server-protocol.h	\
+	protocol/idle-inhibit-unstable-v1-protocol.c	\
+	protocol/idle-inhibit-unstable-v1-server-protocol.h
 
 BUILT_SOURCES += $(nodist_libweston_@LIBWESTON_MAJOR@_la_SOURCES)
 
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 7f92288..62533ca 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -51,6 +51,8 @@ 
 #include <time.h>
 #include <errno.h>
 
+#include <idle-inhibit-unstable-v1-server-protocol.h>
+
 #include "timeline.h"
 
 #include "compositor.h"
@@ -457,6 +459,7 @@  weston_surface_create(struct weston_compositor *compositor)
 
 	wl_signal_init(&surface->destroy_signal);
 	wl_signal_init(&surface->commit_signal);
+	wl_signal_init(&surface->drop_idle_inhibitor_signal);
 
 	surface->compositor = compositor;
 	surface->ref_count = 1;
@@ -4723,6 +4726,102 @@  compositor_bind(struct wl_client *client,
 				       compositor, NULL);
 }
 
+struct weston_idle_inhibitor {
+	struct weston_surface *surface;
+};
+
+/* Called when the idle inhibitor is destroyed on the server-side */
+static void
+destroy_idle_inhibitor(struct wl_resource *resource)
+{
+	struct weston_idle_inhibitor *inhibitor = wl_resource_get_user_data(resource);
+
+	assert(inhibitor);
+
+	if (inhibitor->surface) {
+		inhibitor->surface->inhibit_idling = false;
+		wl_resource_set_user_data(resource, NULL);
+	}
+
+	free(inhibitor);
+}
+
+/* Called when the client requests destruction of the idle inhibitor */
+static void
+idle_inhibitor_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+	struct weston_idle_inhibitor *inhibitor = wl_resource_get_user_data(resource);
+
+	assert(inhibitor);
+
+	wl_resource_destroy(resource);
+
+	/* Send a notification to re-queue any idle behaviors */
+	wl_signal_emit(&inhibitor->surface->drop_idle_inhibitor_signal,
+		       inhibitor->surface);
+}
+
+static const struct zwp_idle_inhibitor_v1_interface idle_inhibitor_interface = {
+	idle_inhibitor_destroy
+};
+
+static void
+idle_inhibit_manager_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+	wl_resource_destroy(resource);
+}
+
+static void
+idle_inhibit_manager_create_inhibitor(struct wl_client *client, struct wl_resource *resource,
+				      uint32_t id, struct wl_resource *surface_resource)
+{
+	struct weston_surface *surface = wl_resource_get_user_data(surface_resource);
+	struct weston_idle_inhibitor *inhibitor;
+	struct wl_resource *cr;
+
+	cr = wl_resource_create(client, &zwp_idle_inhibitor_v1_interface,
+				wl_resource_get_version(resource), id);
+	if (cr == NULL) {
+		wl_client_post_no_memory(client);
+		return;
+	}
+
+	inhibitor = zalloc(sizeof *inhibitor);
+	if (inhibitor == NULL) {
+		wl_client_post_no_memory(client);
+		return;
+	}
+
+	inhibitor->surface = surface;
+	inhibitor->surface->inhibit_idling = true;
+
+	wl_resource_set_implementation(cr, &idle_inhibitor_interface,
+				       inhibitor, destroy_idle_inhibitor);
+}
+
+static const struct zwp_idle_inhibit_manager_v1_interface idle_inhibit_manager_interface = {
+	idle_inhibit_manager_destroy,
+	idle_inhibit_manager_create_inhibitor
+};
+
+static void
+bind_idle_inhibit_manager(struct wl_client *client,
+			  void *data, uint32_t version, uint32_t id)
+{
+	struct wl_resource *resource;
+
+	resource = wl_resource_create(client, &zwp_idle_inhibit_manager_v1_interface,
+				      version, id);
+	if (resource == NULL) {
+		wl_client_post_no_memory(client);
+		return;
+	}
+
+	/* Does not require a destructor since no memory is managed, so pass NULL */
+	wl_resource_set_implementation(resource, &idle_inhibit_manager_interface,
+				       NULL, NULL);
+}
+
 WL_EXPORT int
 weston_environment_get_fd(const char *env)
 {
@@ -4818,6 +4917,10 @@  weston_compositor_create(struct wl_display *display, void *user_data)
 	if (weston_input_init(ec) != 0)
 		goto fail;
 
+	if (!wl_global_create(ec->wl_display, &zwp_idle_inhibit_manager_v1_interface, 1,
+			      ec, bind_idle_inhibit_manager))
+		goto fail;
+
 	wl_list_init(&ec->view_list);
 	wl_list_init(&ec->plane_list);
 	wl_list_init(&ec->layer_list);
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 7a53127..0c688cc 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -618,8 +618,9 @@  enum {
 	WESTON_COMPOSITOR_ACTIVE,	/* normal rendering and events */
 	WESTON_COMPOSITOR_IDLE,		/* shell->unlock called on activity */
 	WESTON_COMPOSITOR_OFFSCREEN,	/* no rendering, no frame events */
-	WESTON_COMPOSITOR_SLEEPING	/* same as offscreen, but also set dpms
-                                         * to off */
+	WESTON_COMPOSITOR_SLEEPING	/* same as offscreen, but also
+					 * attempt to set dpms to off where
+					 * applicable */
 };
 
 struct weston_layer_entry {
@@ -1070,6 +1071,7 @@  struct weston_surface {
 	struct wl_signal destroy_signal; /* callback argument: this surface */
 	struct weston_compositor *compositor;
 	struct wl_signal commit_signal;
+	struct wl_signal drop_idle_inhibitor_signal;
 
 	/** Damage in local coordinates from the client, for tex upload. */
 	pixman_region32_t damage;
@@ -1158,8 +1160,7 @@  struct weston_surface {
 
 	/*
 	 * Indicates the surface prefers no screenblanking, screensaving,
-	 * or other automatic obscurement to kick in while the surface is
-	 * considered "active" by the shell.
+	 * or other automatic obscurement to kick in.
 	 */
 	bool inhibit_idling;