[PATCH rebased] tablet-shell: come back to life

Tiago Vignatti tiago.vignatti at intel.com
Wed Mar 28 03:04:02 PDT 2012


A couple of fixes were made: Weston tablet-shell needed to use weston_layer,
so the compositor could rebuild the surface list correctly when repainting;
homescreen and locking are using the widget + window abstration of toytoolkit;
and widget_set_redraw_handler are being set for widgets redraw.

Also, it was given some basic meaning for lockscreen_button_handler, which
was completely disabled before. As a clean up, I updated the global listener
mechanism on tablet-shell client, using the regular way of registering a
handler instead wl_display_roundtrip -> wl_display_get_global.

Switcher still without code to proper work and the same for tablet-shell
clients, which are not launched. The icons seen on the homescreen are still
quite tiny.

Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
I rebased with master after "clients: Fix a couple of warnings" and anderco's
patchset landed. The only significant change was the addition of
tablet_shell_surface_configure(), which basically calls map() given that
this shell doesn't need to deal with the hassle of set/unset fullscreen.

 clients/tablet-shell.c |  215 +++++++++++++++++++++++++++++++-----------------
 src/tablet-shell.c     |   33 +++++++-
 2 files changed, 173 insertions(+), 75 deletions(-)

diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index 3a532c4..f0145aa 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2011 Intel Corporation
+ * Copyright © 2011, 2012 Intel Corporation
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/wait.h>
 
 #include "window.h"
 #include "cairo-util.h"
@@ -31,16 +32,27 @@
 
 #include "tablet-shell-client-protocol.h"
 
-struct tablet_shell {
+struct tablet {
 	struct display *display;
 	struct tablet_shell *tablet_shell;
 	struct rectangle allocation;
-	struct window *lockscreen;
 	struct window *switcher;
-	struct window *homescreen;
+
+	struct homescreen *homescreen;
+	struct lockscreen *lockscreen;
+};
+
+struct homescreen {
+	struct window *window;
+	struct widget *widget;
 	struct wl_list launcher_list;
 };
 
+struct lockscreen {
+	struct window *window;
+	struct widget *widget;
+};
+
 struct launcher {
 	cairo_surface_t *icon;
 	char *path;
@@ -74,6 +86,16 @@ static const struct config_section config_sections[] = {
 };
 
 static void
+sigchild_handler(int s)
+{
+	int status;
+	pid_t pid;
+
+	while (pid = waitpid(-1, &status, WNOHANG), pid > 0)
+		fprintf(stderr, "child %d exited\n", pid);
+}
+
+static void
 paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
 {
 	cairo_surface_t *image = NULL;
@@ -97,16 +119,16 @@ paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
 		cairo_surface_destroy(image);
 		cairo_paint(cr);
 	} else {
-		fprintf(stderr, "couldn't load backgrond image: %s\n",
-			key_lockscreen_background);
+		fprintf(stderr, "couldn't load background image: %s\n", path);
 		cairo_set_source_rgb(cr, 0.2, 0, 0);
 		cairo_paint(cr);
 	}
 }
 
 static void
-homescreen_draw(struct tablet_shell *shell)
+homescreen_draw(struct widget *widget, void *data)
 {
+	struct homescreen *homescreen = data;
 	cairo_surface_t *surface;
 	struct rectangle allocation;
 	cairo_pattern_t *pattern;
@@ -116,11 +138,10 @@ homescreen_draw(struct tablet_shell *shell)
 	const int rows = 4, columns = 5, icon_width = 128, icon_height = 128;
 	int x, y, i, width, height, vmargin, hmargin, vpadding, hpadding;
 
-	window_create_surface(shell->homescreen);
-	window_get_allocation(shell->homescreen, &allocation);
-	surface = window_get_surface(shell->homescreen);
+	surface = window_get_surface(homescreen->window);
 	cr = cairo_create(surface);
 
+	widget_get_allocation(widget, &allocation);
 	paint_background(cr, key_homescreen_background, &allocation);
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
@@ -137,7 +158,7 @@ homescreen_draw(struct tablet_shell *shell)
 	y = vmargin;
 	i = 0;
 
-	wl_list_for_each(launcher, &shell->launcher_list, link) {
+	wl_list_for_each(launcher, &homescreen->launcher_list, link) {
 		pattern = cairo_pattern_create_for_surface(launcher->icon);
 		cairo_matrix_init_scale(&matrix, 2.0, 2.0);
 		cairo_matrix_translate(&matrix, -x, -y);
@@ -155,26 +176,24 @@ homescreen_draw(struct tablet_shell *shell)
 		}
 	}
 
-	cairo_surface_flush(surface);
+	cairo_destroy(cr);
 	cairo_surface_destroy(surface);
-	window_flush(shell->homescreen);
 }
 
-
 static void
-lockscreen_draw(struct tablet_shell *shell)
+lockscreen_draw(struct widget *widget, void *data)
 {
+	struct lockscreen *lockscreen = data;
 	cairo_surface_t *surface;
 	cairo_surface_t *icon;
 	struct rectangle allocation;
 	cairo_t *cr;
 	int width, height;
 
-	window_create_surface(shell->lockscreen);
-	window_get_allocation(shell->lockscreen, &allocation);
-	surface = window_get_surface(shell->lockscreen);
+	surface = window_get_surface(lockscreen->window);
 	cr = cairo_create(surface);
 
+	widget_get_allocation(widget, &allocation);
 	paint_background(cr, key_lockscreen_background, &allocation);
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
@@ -185,37 +204,88 @@ lockscreen_draw(struct tablet_shell *shell)
 				 allocation.x + (allocation.width - width) / 2,
 				 allocation.y + (allocation.height - height) / 2);
 	cairo_paint(cr);
+	cairo_destroy(cr);
 	cairo_surface_destroy(icon);
-
-	cairo_surface_flush(surface);
 	cairo_surface_destroy(surface);
-	window_flush(shell->lockscreen);
+}
+
+static void
+lockscreen_button_handler(struct widget *widget,
+			  struct input *input, uint32_t time,
+			  int button, int state, void *data)
+{
+	struct lockscreen *lockscreen = data;
+
+	if (state && lockscreen->window) {
+		window_destroy(lockscreen->window);
+		lockscreen->window = NULL;
+	}
+}
+
+static struct homescreen *
+homescreen_create(struct tablet *tablet)
+{
+	struct homescreen *homescreen;
+
+	homescreen = malloc (sizeof *homescreen);
+	memset(homescreen, 0, sizeof *homescreen);
+
+	homescreen->window = window_create(tablet->display);
+	homescreen->widget =
+		window_add_widget(homescreen->window, homescreen);
+	window_set_custom(homescreen->window);
+	window_set_user_data(homescreen->window, homescreen);
+	window_set_title(homescreen->window, "homescreen");
+	widget_set_redraw_handler(homescreen->widget, homescreen_draw);
+
+	return homescreen;
+}
+
+static struct lockscreen *
+lockscreen_create(struct tablet *tablet)
+{
+	struct lockscreen *lockscreen;
+
+	lockscreen = malloc (sizeof *lockscreen);
+	memset(lockscreen, 0, sizeof *lockscreen);
+
+	lockscreen->window = window_create(tablet->display);
+	lockscreen->widget =
+		window_add_widget(lockscreen->window, lockscreen);
+	window_set_user_data(lockscreen->window, lockscreen);
+	window_set_title(lockscreen->window, "lockscreen");
+	window_set_custom(lockscreen->window);
+	widget_set_redraw_handler(lockscreen->widget, lockscreen_draw);
+	widget_set_button_handler(lockscreen->widget,
+				  lockscreen_button_handler);
+
+	return lockscreen;
 }
 
 static void
 show_lockscreen(void *data, struct tablet_shell *tablet_shell)
 {
-	struct tablet_shell *shell = data;
+	struct tablet *tablet = data;
 
-	shell->lockscreen = window_create(shell->display);
-	window_set_user_data(shell->lockscreen, shell);
-	window_set_custom(shell->lockscreen);
+	tablet->lockscreen = lockscreen_create(tablet);
+	tablet_shell_set_lockscreen(tablet->tablet_shell,
+			window_get_wl_surface(tablet->lockscreen->window));
 
-	tablet_shell_set_lockscreen(shell->tablet_shell,
-				    window_get_wl_surface(shell->lockscreen));
-	lockscreen_draw(shell);
+	widget_schedule_resize(tablet->lockscreen->widget,
+			       tablet->allocation.width,
+			       tablet->allocation.height);
 }
 
 static void
 show_switcher(void *data, struct tablet_shell *tablet_shell)
 {
-	struct tablet_shell *shell = data;
+	struct tablet *tablet = data;
 
-	shell->switcher = window_create(shell->display);
-	window_set_user_data(shell->switcher, shell);
-	window_set_custom(shell->switcher);
-	tablet_shell_set_switcher(shell->tablet_shell,
-				  window_get_wl_surface(shell->switcher));
+	tablet->switcher = window_create(tablet->display);
+	window_set_user_data(tablet->switcher, tablet);
+	window_set_custom(tablet->switcher);
+	tablet_shell_set_switcher(tablet->tablet_shell,
+				  window_get_wl_surface(tablet->switcher));
 }
 
 static void
@@ -229,39 +299,12 @@ static const struct tablet_shell_listener tablet_shell_listener = {
 	hide_switcher
 };
 
-static struct tablet_shell *
-tablet_shell_create(struct display *display, uint32_t id)
-{
-	struct tablet_shell *shell;
-	struct output *output;
-
-	shell = malloc(sizeof *shell);
-
-	shell->display = display;
-	shell->tablet_shell =
-		wl_display_bind(display_get_display(display),
-				id, &tablet_shell_interface);
-	tablet_shell_add_listener(shell->tablet_shell,
-				  &tablet_shell_listener, shell);
-	output = display_get_output(display);
-	output_get_allocation(output, &shell->allocation);
-
-	shell->homescreen = window_create(display);
-	window_set_user_data(shell->homescreen, shell);
-	window_set_custom(shell->homescreen);
-
-	tablet_shell_set_homescreen(shell->tablet_shell,
-				    window_get_wl_surface(shell->homescreen));
-	wl_list_init(&shell->launcher_list);
-
-	return shell;
-}
-
 static void
-tablet_shell_add_launcher(struct tablet_shell *shell,
+tablet_shell_add_launcher(struct tablet *tablet,
 			  const char *icon, const char *path)
 {
 	struct launcher *launcher;
+	struct homescreen *homescreen = tablet->homescreen;
 
 	launcher = malloc(sizeof *launcher);
 	launcher->path = strdup(path);
@@ -272,20 +315,20 @@ tablet_shell_add_launcher(struct tablet_shell *shell,
 		return;
 	}
 
-	wl_list_insert(&shell->launcher_list, &launcher->link);
+	wl_list_insert(&homescreen->launcher_list, &launcher->link);
 }
 
 static void
 launcher_section_done(void *data)
 {
-	struct tablet_shell *shell = data;
+	struct tablet *tablet = data;
 
 	if (key_launcher_icon == NULL || key_launcher_path == NULL) {
 		fprintf(stderr, "invalid launcher section\n");
 		return;
 	}
 
-	tablet_shell_add_launcher(shell, key_launcher_icon, key_launcher_path);
+	tablet_shell_add_launcher(tablet, key_launcher_icon, key_launcher_path);
 
 	free(key_launcher_icon);
 	key_launcher_icon = NULL;
@@ -293,12 +336,26 @@ launcher_section_done(void *data)
 	key_launcher_path = NULL;
 }
 
+static void
+global_handler(struct wl_display *display, uint32_t id,
+		const char *interface, uint32_t version, void *data)
+{
+	struct tablet *tablet = data;
+
+	if (!strcmp(interface, "tablet_shell")) {
+		tablet->tablet_shell =
+			wl_display_bind(display, id, &tablet_shell_interface);
+		tablet_shell_add_listener(tablet->tablet_shell,
+				&tablet_shell_listener, tablet);
+	}
+}
+
 int main(int argc, char *argv[])
 {
+	struct tablet tablet = { 0 };
 	struct display *display;
 	char *config_file;
-	uint32_t id;
-	struct tablet_shell *shell;
+	struct output *output;
 
 	display = display_create(argc, argv);
 	if (display == NULL) {
@@ -306,19 +363,29 @@ int main(int argc, char *argv[])
 		return -1;
 	}
 
-	wl_display_roundtrip(display_get_display(display));
-	id = wl_display_get_global(display_get_display(display),
-				   "tablet_shell", 1);
-	shell = tablet_shell_create(display, id);
+	tablet.display = display;
+
+	wl_display_add_global_listener(display_get_display(tablet.display),
+			global_handler, &tablet);
+
+	tablet.homescreen = homescreen_create(&tablet);
+	tablet_shell_set_homescreen(tablet.tablet_shell,
+			window_get_wl_surface(tablet.homescreen->window));
+	wl_list_init(&tablet.homescreen->launcher_list);
 
 	config_file = config_file_path("weston.ini");
 	parse_config_file(config_file,
 			  config_sections, ARRAY_LENGTH(config_sections),
-			  shell);
+			  &tablet);
 	free(config_file);
 
-	homescreen_draw(shell);
+	signal(SIGCHLD, sigchild_handler);
 
+	output = display_get_output(tablet.display);
+	output_get_allocation(output, &tablet.allocation);
+	widget_schedule_resize(tablet.homescreen->widget,
+			tablet.allocation.width,
+			tablet.allocation.height);
 	display_run(display);
 
 	return 0;
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index fe215ab..cb7211c 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -57,8 +57,10 @@ struct tablet_shell {
 
 	struct weston_surface *lockscreen_surface;
 	struct wl_listener lockscreen_listener;
+	struct weston_layer lockscreen_layer;
 
 	struct weston_surface *home_surface;
+	struct weston_layer homescreen_layer;
 
 	struct weston_surface *switcher_surface;
 	struct wl_listener switcher_listener;
@@ -113,11 +115,16 @@ tablet_shell_map(struct weston_shell *base, struct weston_surface *surface,
 	weston_surface_configure(surface, 0, 0, width, height);
 
 	if (surface == shell->lockscreen_surface) {
-		/* */
+			wl_list_insert(&shell->lockscreen_layer.surface_list,
+					&surface->layer_link);
 	} else if (surface == shell->switcher_surface) {
 		/* */
 	} else if (surface == shell->home_surface) {
 		if (shell->state == STATE_STARTING) {
+	                /* homescreen always visible, at the bottom */
+			wl_list_insert(&shell->homescreen_layer.surface_list,
+					&surface->layer_link);
+
 			tablet_shell_set_state(shell, STATE_LOCKED);
 			shell->previous_state = STATE_HOME;
 			tablet_shell_send_show_lockscreen(&shell->resource);
@@ -144,6 +151,17 @@ tablet_shell_configure(struct weston_shell *base,
 }
 
 static void
+tablet_shell_surface_configure(struct weston_surface *es, int32_t sx,
+			       int32_t sy)
+{
+	struct weston_shell *shell = es->compositor->shell;
+
+	if (!weston_surface_is_mapped(es))
+		tablet_shell_map(shell, es, es->buffer->width,
+				 es->buffer->height, sx, sy);
+}
+
+static void
 handle_lockscreen_surface_destroy(struct wl_listener *listener,
 				  struct wl_resource *resource, uint32_t time)
 {
@@ -165,6 +183,7 @@ tablet_shell_set_lockscreen(struct wl_client *client,
 
 	weston_surface_set_position(es, 0, 0);
 	shell->lockscreen_surface = es;
+	shell->lockscreen_surface->configure = tablet_shell_surface_configure;
 	shell->lockscreen_listener.func = handle_lockscreen_surface_destroy;
 	wl_list_insert(es->surface.resource.destroy_listener_list.prev,
 		       &shell->lockscreen_listener.link);
@@ -211,6 +230,8 @@ tablet_shell_set_homescreen(struct wl_client *client,
 	struct tablet_shell *shell = resource->data;
 
 	shell->home_surface = surface_resource->data;
+	shell->home_surface->configure = tablet_shell_surface_configure;
+
 	weston_surface_set_position(shell->home_surface, 0, 0);
 }
 
@@ -506,6 +527,12 @@ tablet_shell_destroy(struct weston_shell *base)
 	struct tablet_shell *shell =
 		container_of(base, struct tablet_shell, shell);
 
+	if (shell->home_surface)
+		shell->home_surface->configure = NULL;
+
+	if (shell->lockscreen_surface)
+		shell->lockscreen_surface->configure = NULL;
+
 	wl_event_source_remove(shell->long_press_source);
 	free(shell);
 }
@@ -553,6 +580,10 @@ shell_init(struct weston_compositor *compositor)
 	shell->shell.configure = tablet_shell_configure;
 	shell->shell.destroy = tablet_shell_destroy;
 
+	weston_layer_init(&shell->homescreen_layer,
+			  &compositor->cursor_layer.link);
+	weston_layer_init(&shell->lockscreen_layer,
+			  &compositor->cursor_layer.link);
 	launch_ux_daemon(shell);
 
 	tablet_shell_set_state(shell, STATE_STARTING);
-- 
1.7.5.4



More information about the wayland-devel mailing list