[RFC patch] desktop-shell: locking communications

Pekka Paalanen ppaalanen at gmail.com
Fri Nov 4 06:42:31 PDT 2011


WIP
---
 clients/desktop-shell.c    |   11 +++++++-
 compositor/compositor.c    |    2 +
 compositor/compositor.h    |    1 +
 compositor/shell.c         |   58 +++++++++++++++++++++++++++++++++++++++++--
 protocol/desktop-shell.xml |   12 +++++++++
 5 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index b915723..7189d02 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -277,8 +277,17 @@ desktop_shell_configure(void *data,
 	}
 }
 
+static void
+desktop_shell_prepare_lock_surface(void *data,
+				   struct desktop_shell *desktop_shell)
+{
+	/* no-op for now */
+	desktop_shell_unlock(desktop_shell);
+}
+
 static const struct desktop_shell_listener listener = {
-	desktop_shell_configure
+	desktop_shell_configure,
+	desktop_shell_prepare_lock_surface
 };
 
 static void
diff --git a/compositor/compositor.c b/compositor/compositor.c
index a516837..aac9e31 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -1336,6 +1336,8 @@ wlsc_compositor_wake(struct wlsc_compositor *compositor)
 	if (compositor->idle_inhibit)
 		return;
 
+	compositor->shell->unlock(compositor->shell);
+
 	wlsc_compositor_fade(compositor, 0.0);
 	compositor->state = WLSC_COMPOSITOR_ACTIVE;
 
diff --git a/compositor/compositor.h b/compositor/compositor.h
index 421b80e..9c5f73d 100644
--- a/compositor/compositor.h
+++ b/compositor/compositor.h
@@ -163,6 +163,7 @@ struct wlsc_shell {
 			 struct wlsc_surface *es,
 			 struct wlsc_input_device *device, uint32_t time);
 	void (*lock)(struct wlsc_shell *shell);
+	void (*unlock)(struct wlsc_shell *shell);
 	void (*attach)(struct wlsc_shell *shell, struct wlsc_surface *surface);
 	void (*set_selection_focus)(struct wlsc_shell *shell,
 				    struct wl_selection *selection,
diff --git a/compositor/shell.c b/compositor/shell.c
index b409d50..8b56a24 100644
--- a/compositor/shell.c
+++ b/compositor/shell.c
@@ -22,6 +22,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
 #include <linux/input.h>
@@ -44,7 +45,10 @@ struct wl_shell {
 	struct {
 		struct wlsc_process process;
 		struct wl_client *client;
+		struct wl_resource *desktop_shell;
 	} child;
+
+	bool locked;
 };
 
 struct wlsc_move_grab {
@@ -825,9 +829,27 @@ desktop_shell_set_panel(struct wl_client *client,
 			       output->current->height);
 }
 
+static void
+desktop_shell_set_lock_surface(struct wl_client *client,
+			       struct wl_resource *resource,
+			       struct wl_resource *surface_resource)
+{
+}
+
+static void
+desktop_shell_unlock(struct wl_client *client,
+		     struct wl_resource *resource)
+{
+	struct wl_shell *shell = resource->data;
+
+	shell->locked = false;
+}
+
 static const struct desktop_shell_interface desktop_shell_implementation = {
 	desktop_shell_set_background,
-	desktop_shell_set_panel
+	desktop_shell_set_panel,
+	desktop_shell_set_lock_surface,
+	desktop_shell_unlock
 };
 
 static void
@@ -914,8 +936,26 @@ activate(struct wlsc_shell *base, struct wlsc_surface *es,
 }
 
 static void
-lock(struct wlsc_shell *shell)
+lock(struct wlsc_shell *base)
+{
+	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
+
+	shell->locked = true;
+}
+
+static void
+unlock(struct wlsc_shell *base)
 {
+	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
+
+	/* If desktop-shell client has gone away, unlock immediately. */
+	if (!shell->child.desktop_shell) {
+		shell->locked = false;
+		return;
+	}
+
+	wl_resource_post_event(shell->child.desktop_shell,
+			       DESKTOP_SHELL_PREPARE_LOCK_SURFACE);
 }
 
 static void
@@ -1014,6 +1054,14 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 }
 
 static void
+unbind_desktop_shell(struct wl_resource *resource)
+{
+	struct wl_shell *shell = resource->data;
+	shell->child.desktop_shell = NULL;
+	free(resource);
+}
+
+static void
 bind_desktop_shell(struct wl_client *client,
 		   void *data, uint32_t version, uint32_t id)
 {
@@ -1024,8 +1072,11 @@ bind_desktop_shell(struct wl_client *client,
 					&desktop_shell_implementation,
 					id, shell);
 
-	if (client == shell->child.client)
+	if (client == shell->child.client) {
+		resource->destroy = unbind_desktop_shell;
+		shell->child.desktop_shell = resource;
 		return;
+	}
 
 	wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
 			       "permission to bind desktop_shell denied");
@@ -1048,6 +1099,7 @@ shell_init(struct wlsc_compositor *ec, struct wl_array *opts)
 	shell->compositor = ec;
 	shell->shell.activate = activate;
 	shell->shell.lock = lock;
+	shell->shell.unlock = unlock;
 	shell->shell.attach = attach;
 	shell->shell.set_selection_focus = wlsc_selection_set_focus;
 
diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml
index 438773d..d099925 100644
--- a/protocol/desktop-shell.xml
+++ b/protocol/desktop-shell.xml
@@ -9,6 +9,12 @@
       <arg name="surface" type="object" interface="wl_surface"/>
     </request>
 
+    <request name="set_lock_surface">
+      <arg name="surface" type="object" interface="wl_surface"/>
+    </request>
+
+    <request name="unlock"/>
+
     <!-- We'll fold most of wl_shell into this interface and then
          they'll share the configure event.  -->
     <event name="configure">
@@ -19,6 +25,12 @@
       <arg name="height" type="int"/>
     </event>
 
+    <!-- Tell the shell we want it to create and set the lock surface,
+         which is a GUI asking the user to unlock the screen. The lock
+         surface is announced with 'set_lock_surface'. Whether or not
+         the shell actually implements locking, it MUST send 'unlock'
+         request to let the normal desktop resume. -->
+    <event name="prepare_lock_surface"/>
   </interface>
 
 </protocol>
-- 
1.7.3.4



More information about the wayland-devel mailing list