[RFC PATCH 08/12] tablet-shell: support the surface who don't response the event

juan.j.zhao at linux.intel.com juan.j.zhao at linux.intel.com
Fri Aug 3 04:22:03 PDT 2012


From: Juan Zhao <juan.j.zhao at intel.com>

Add a black surface under the application's surface and center it on screen.

Signed-off-by: Tang Ning <tecton69 at gmail.com>
---
 clients/tablet-shell.c |  26 +++---
 src/tablet-shell.c     | 210 ++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 173 insertions(+), 63 deletions(-)

diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index 37c0a48..c2ac525 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -48,11 +48,13 @@ struct homescreen {
 	struct window *window;
 	struct widget *widget;
 	struct wl_list layout_list;
+	cairo_surface_t *image;
 };
 
 struct lockscreen {
 	struct window *window;
 	struct widget *widget;
+	cairo_surface_t *image;
 };
 
 /* container of launchers on background */
@@ -147,16 +149,14 @@ sigchild_handler(int s)
 }
 
 static void
-paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
+paint_background(cairo_t *cr, cairo_surface_t *image,
+		 struct rectangle *allocation)
 {
-	cairo_surface_t *image = NULL;
 	cairo_pattern_t *pattern;
 	cairo_matrix_t matrix;
 	double sx, sy;
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-	if (path)
-		image = load_cairo_surface(path);
 	if (image) {
 		pattern = cairo_pattern_create_for_surface(image);
 		sx = (double) cairo_image_surface_get_width(image) /
@@ -167,10 +167,9 @@ paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
 		cairo_pattern_set_matrix(pattern, &matrix);
 		cairo_set_source(cr, pattern);
 		cairo_pattern_destroy (pattern);
-		cairo_surface_destroy(image);
 		cairo_paint(cr);
 	} else {
-		fprintf(stderr, "couldn't load background image: %s\n", path);
+// 		fprintf(stderr, "couldn't load background image: %s\n", path);
 		cairo_set_source_rgb(cr, 0.2, 0, 0);
 		cairo_paint(cr);
 	}
@@ -178,7 +177,8 @@ paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
 
 /*simple draw trash function*/
 static void
-homescreen_draw_trash(void *data, int x, int y){
+homescreen_draw_trash(void *data, int x, int y)
+{
 	int w, h;
 	cairo_t *cr;
 	cairo_surface_t *surface;
@@ -237,7 +237,11 @@ homescreen_draw(struct widget *widget, void *data)
 	cr = cairo_create(surface);
 
 	widget_get_allocation(widget, &allocation);
-	paint_background(cr, key_homescreen_background, &allocation);
+	if (homescreen->image == NULL && key_homescreen_background) {
+		homescreen->image =
+			load_cairo_surface(key_homescreen_background);
+	}
+	paint_background(cr, homescreen->image, &allocation);
 
 	/* draw current layout */
 	wl_list_for_each(layout, &homescreen->layout_list, link) {
@@ -305,8 +309,12 @@ lockscreen_draw(struct widget *widget, void *data)
 	surface = window_get_surface(lockscreen->window);
 	cr = cairo_create(surface);
 
+	if (lockscreen->image == NULL && key_lockscreen_background) {
+		lockscreen->image =
+			load_cairo_surface(key_lockscreen_background);
+	}
 	widget_get_allocation(widget, &allocation);
-	paint_background(cr, key_lockscreen_background, &allocation);
+	paint_background(cr, lockscreen->image, &allocation);
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
 	icon = load_cairo_surface(key_lockscreen_icon);
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index b4dfe55..55522be 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -29,6 +29,7 @@
 
 #include "compositor.h"
 #include "tablet-shell-server-protocol.h"
+#include "log.h"
 
 /*
  * TODO: Don't fade back from black until we've received a lockscreen
@@ -86,6 +87,7 @@ struct shell_surface {
 
 	struct weston_surface *surface;
 	struct weston_surface *parent_surface;
+	struct weston_surface *black_surface;
 	struct wl_listener surface_destroy_listener;
 	struct tablet_shell *shell;
 
@@ -143,6 +145,50 @@ ping_timer_destroy(struct shell_surface *shsurf)
 	free(shsurf->ping_timer);
 	shsurf->ping_timer = NULL;
 }
+
+static void
+destroy_shell_surface(struct shell_surface *shsurf)
+{
+	wl_list_remove(&shsurf->surface_destroy_listener.link);
+	shsurf->surface->configure = NULL;
+	ping_timer_destroy(shsurf);
+
+	if (shsurf->black_surface)
+	{
+		wl_list_remove(&shsurf->black_surface->layer_link);
+		weston_surface_destroy(shsurf->black_surface);
+	}
+	wl_list_remove(&shsurf->link);
+	free(shsurf);
+}
+
+static void
+shell_destroy_shell_surface(struct wl_resource *resource)
+{
+	struct shell_surface *shsurf = resource->data;
+	destroy_shell_surface(shsurf);
+}
+
+static void
+shell_handle_surface_destroy(struct wl_listener *listener, void *data)
+{
+	struct shell_surface *shsurf =
+		container_of(listener, struct shell_surface,
+			     surface_destroy_listener);
+	struct tablet_shell *shell = shsurf->shell;
+	if (shell->client_resource.client) {
+		wl_resource_destroy(&shell->client_resource);
+		shell->client_resource.client = NULL;
+	}
+	if (shsurf->resource.client) {
+		wl_resource_destroy(&shsurf->resource);
+	} else {
+		wl_signal_emit(&shsurf->resource.destroy_signal,
+			       &shsurf->resource);
+		destroy_shell_surface(shsurf);
+	}
+}
+
 static void
 shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
 		uint32_t serial)
@@ -166,6 +212,7 @@ shell_surface_set_title(struct wl_client *client,
 {
 	return;
 }
+
 static void
 shell_surface_set_class(struct wl_client *client,
 			struct wl_resource *resource, const char *class)
@@ -179,6 +226,7 @@ shell_surface_move(struct wl_client *client, struct wl_resource *resource,
 {
 	return;
 }
+
 static void
 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
 			struct wl_resource *seat_resource, uint32_t serial,
@@ -200,8 +248,21 @@ shell_surface_set_transient(struct wl_client *client,
 			struct wl_resource *parent_resource,
 			int x, int y, uint32_t flags)
 {
-	return;
+	struct shell_surface *shsurf = resource->data;
+	struct tablet_shell *shell = shsurf->shell;
+	if (shell->client_resource.client) {
+		wl_resource_destroy(&shell->client_resource);
+		shell->client_resource.client = NULL;
+	}
+	if (shsurf->resource.client) {
+		wl_resource_destroy(&shsurf->resource);
+	} else {
+		wl_signal_emit(&shsurf->resource.destroy_signal,
+			       &shsurf->resource);
+		destroy_shell_surface(shsurf);
+	}
 }
+
 static void
 shell_surface_set_fullscreen(struct wl_client *client,
 			struct wl_resource *resource,
@@ -241,6 +302,7 @@ shell_surface_set_maximized(struct wl_client *client,
 {
 	return;
 }
+
 static const struct wl_shell_surface_interface shell_surface_implementation = {
 	shell_surface_pong,
 	shell_surface_move,
@@ -254,40 +316,6 @@ static const struct wl_shell_surface_interface shell_surface_implementation = {
 	shell_surface_set_class
 };
 
-static void
-destroy_shell_surface(struct shell_surface *shsurf)
-{
-	wl_list_remove(&shsurf->surface_destroy_listener.link);
-	shsurf->surface->configure = NULL;
-	ping_timer_destroy(shsurf);
-
-	wl_list_remove(&shsurf->link);
-	free(shsurf);
-	weston_log("shell surface destroyed\n");
-}
-
-static void
-shell_destroy_shell_surface(struct wl_resource *resource)
-{
-	struct shell_surface *shsurf = resource->data;
-	destroy_shell_surface(shsurf);
-}
-
-static void
-shell_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
-	struct shell_surface *shsurf =
-		container_of(listener, struct shell_surface,
-			     surface_destroy_listener);
-	if (shsurf->resource.client) {
-		wl_resource_destroy(&shsurf->resource);
-	} else {
-		wl_signal_emit(&shsurf->resource.destroy_signal,
-				&shsurf->resource);
-		destroy_shell_surface(shsurf);
-	}
-}
-
 static struct shell_surface *
 create_shell_surface(void *shell, struct weston_surface *surface,
 			const struct weston_shell_client *client)
@@ -351,8 +379,6 @@ shell_get_shell_surface(struct wl_client *client,
 	struct tablet_shell *shell = resource->data;
 	struct shell_surface *shsurf;
 
-	weston_log("get shell surface\n");
-
 	if (get_shell_surface(surface)) {
 		wl_resource_post_error(surface_resource,
 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
@@ -474,15 +500,90 @@ tablet_shell_surface_configure(struct weston_surface *surface,
 }
 
 static void
+center_on_output(struct weston_surface *surface, struct weston_output *output)
+{
+	struct weston_mode *mode = output->current;
+	GLfloat x = (mode->width - surface->buffer->width) / 2;
+	GLfloat y = (mode->height - surface->buffer->height) / 2;
+
+	weston_surface_configure(surface, output->x + x, output->y + y,
+				 surface->buffer->width,
+				 surface->buffer->height);
+}
+
+static void
+black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+{
+	return;
+}
+
+static struct weston_surface *
+create_black_surface(struct weston_compositor *ec,
+		     struct weston_surface *fs_surface,
+		     GLfloat x, GLfloat y, int w, int h)
+{
+	struct weston_surface *surface = NULL;
+
+	surface = weston_surface_create(ec);
+	if (surface == NULL) {
+		weston_log("no memory\n");
+		return NULL;
+	}
+
+	surface->configure = black_surface_configure;
+	surface->private = fs_surface;
+	weston_surface_configure(surface, x, y, w, h);
+	weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
+	return surface;
+}
+
+static void
+shell_stack_fullscreen(struct shell_surface *shsurf)
+{
+	struct weston_surface *surface = shsurf->surface;
+	struct weston_output *output = surface->output;
+	struct tablet_shell *shell = shsurf->shell;
+
+	wl_list_remove(&surface->layer_link);
+	wl_list_insert(&shell->application_layer.surface_list,
+		       &surface->layer_link);
+	weston_surface_damage(surface);
+
+	if (!shsurf->black_surface)
+		shsurf->black_surface =
+			create_black_surface(surface->compositor,
+					     surface,
+					     output->x, output->y,
+					     output->current->width,
+					     output->current->height);
+
+	wl_list_remove(&shsurf->black_surface->layer_link);
+	wl_list_insert(&surface->layer_link,
+		       &shsurf->black_surface->layer_link);
+	weston_surface_damage(shsurf->black_surface);
+}
+
+static void
+shell_map_fullscreen(struct shell_surface *shsurf)
+{
+	shell_stack_fullscreen(shsurf);
+}
+
+static void
 configure(struct tablet_shell *shell, struct weston_surface *surface,
 	  GLfloat x, GLfloat y, int32_t width, int32_t height)
 {
+	struct shell_surface *shsurf;
+
+	shsurf = get_shell_surface(surface);
 	surface->geometry.x = x;
 	surface->geometry.y = y;
 	surface->geometry.width = width;
 	surface->geometry.height = height;
 	surface->geometry.dirty = 1;
 
+	shell_stack_fullscreen(shsurf);
+	center_on_output(surface, surface->output);
 	weston_surface_assign_output(surface);
 }
 
@@ -491,24 +592,28 @@ shell_surface_configure(struct weston_surface *surface,
 			int32_t sx, int32_t sy)
 {
 	struct tablet_shell *shell = get_shell(surface->compositor);
-	int32_t width, height;
+	struct shell_surface *shsurf = get_shell_surface(surface);
+	struct weston_seat *seat;
 
 	if (!weston_surface_is_mapped(surface)) {
-		width = surface->buffer->width;
-		height = surface->buffer->height;
-
-		weston_surface_configure(surface, 0, 0, width, height);
-// 		tablet_shell_set_state(shell, STATE_TASK);
+		tablet_shell_set_state(shell, STATE_TASK);
 
 		wl_list_insert(&shell->application_layer.surface_list,
 				&surface->layer_link);
+
 		// have a try
-		tablet_client_send_set_fullscreen(&shell->client_resource);
+		if (shell->client_resource.client)
+			tablet_client_send_set_fullscreen(
+				&shell->client_resource);
 		weston_surface_assign_output(surface);
+		center_on_output(surface, surface->output);
+		shell_map_fullscreen(shsurf);
+		wl_list_for_each(seat, &surface->compositor->seat_list, link)
+			weston_surface_activate(surface, seat);
 	}
 	if (sx != 0 || sy != 0 ||
-		 surface->geometry.width != surface->buffer->width ||
-		 surface->geometry.height != surface->buffer->height) {
+		surface->geometry.width != surface->buffer->width ||
+		surface->geometry.height != surface->buffer->height) {
 		GLfloat from_x, from_y;
 		GLfloat to_x, to_y;
 
@@ -848,10 +953,10 @@ home_key_binding(struct wl_seat *seat, uint32_t time, uint32_t key, void *data)
 
 static void
 terminate_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
-				  void *data)
+		  void *data)
 {
 	struct weston_compositor *compositor = data;
-			wl_display_terminate(compositor->wl_display);
+	wl_display_terminate(compositor->wl_display);
 }
 
 static void
@@ -863,10 +968,11 @@ click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
 	weston_surface_activate(focus, seat);
 }
 
-	static void
+static void
 force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
-		void *data)
+		   void *data)
 {
+	struct tablet_shell *shell = data;
 	struct wl_client *client;
 	pid_t pid;
 	uid_t uid;
@@ -876,12 +982,9 @@ force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
 	wl_client_get_credentials(client, &pid, &uid, &gid);
 
 	kill(pid, SIGKILL);
-<<<<<<< HEAD
-=======
 	tablet_shell_set_state(shell, STATE_HOME);
 	weston_surface_damage(shell->home_surface);
 	weston_compositor_schedule_repaint(shell->compositor);
->>>>>>> 6bc1b22... update for repaint after kill an client
 }
 
 static void
@@ -916,7 +1019,6 @@ bind_tablet_client(struct wl_client *client, void *data, uint32_t version,
 		   uint32_t id)
 {
 	struct tablet_shell *shell = data;
-	fprintf(stderr, "bind_tablet_client\n");
 	shell->client_resource.object.id = id;
 	shell->client_resource.object.interface = &tablet_client_interface;
 	shell->client_resource.object.implementation =
-- 
1.7.11



More information about the wayland-devel mailing list