From: Alex Wu <zhiwen...@linux.intel.com> All the fullscreen things (black surface, raise atop panels, transform, positioning) are handled in map() or configure().
Signed-off-by: Alex Wu <zhiwen...@linux.intel.com> Signed-off-by: Juan Zhao <juan.j.z...@linux.intel.com> --- src/shell.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 214 insertions(+), 17 deletions(-) diff --git a/src/shell.c b/src/shell.c index d949d0c..add9547 100644 --- a/src/shell.c +++ b/src/shell.c @@ -38,6 +38,8 @@ struct shell_surface; +#define INVALID_X (-1) +#define INVALID_Y (-1) struct wl_shell { struct weston_compositor *compositor; struct weston_shell shell; @@ -108,6 +110,13 @@ struct shell_surface { int32_t initial_up; } popup; + struct { + enum wl_shell_surface_fullscreen_method type; + struct weston_transform transform; /* matrix from x, y */ + uint32_t framerate; + struct weston_surface *black_surface; + } fullscreen; + struct weston_output *fullscreen_output; struct weston_output *output; struct wl_list link; @@ -134,6 +143,14 @@ struct rotate_grab { }; static void +activate(struct weston_shell *base, struct weston_surface *es, + struct weston_input_device *device, uint32_t time); + +static void +center_on_output(struct weston_surface *surface, + struct weston_output *output); + +static void shell_configuration(struct wl_shell *shell) { char *config_file; @@ -303,7 +320,8 @@ weston_surface_resize(struct shell_surface *shsurf, { struct weston_resize_grab *resize; - /* FIXME: Reject if fullscreen */ + if (shsurf->type == SHELL_SURFACE_FULLSCREEN) + return 0; if (edges == 0 || edges > 15 || (edges & 3) == 3 || (edges & 12) == 12) @@ -334,7 +352,8 @@ shell_surface_resize(struct wl_client *client, struct wl_resource *resource, struct weston_input_device *wd = input_resource->data; struct shell_surface *shsurf = resource->data; - /* FIXME: Reject if fullscreen */ + if (shsurf->type == SHELL_SURFACE_FULLSCREEN) + return; if (wd->input_device.button_count == 0 || wd->input_device.grab_time != time || @@ -352,15 +371,22 @@ get_default_output(struct weston_compositor *compositor) struct weston_output, link); } +static void +shell_unset_fullscreen(struct shell_surface *shsurf) +{ + shsurf->fullscreen_output = NULL; + shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; + shsurf->surface->force_configure = 1; + wl_list_remove(&shsurf->fullscreen.transform.link); + wl_list_init(&shsurf->fullscreen.transform.link); +} + static int reset_shell_surface_type(struct shell_surface *surface) { switch (surface->type) { case SHELL_SURFACE_FULLSCREEN: - weston_surface_set_position(surface->surface, - surface->saved_x, - surface->saved_y); - surface->fullscreen_output = NULL; + shell_unset_fullscreen(surface); break; case SHELL_SURFACE_MAXIMIZED: surface->output = get_default_output(surface->surface->compositor); @@ -487,6 +513,109 @@ shell_surface_set_maximized(struct wl_client *client, shsurf->type = SHELL_SURFACE_MAXIMIZED; } +static struct weston_surface * +create_black_surface(struct weston_compositor *ec) +{ + struct weston_surface *surface = NULL; + + surface = weston_surface_create(ec); + if (surface == NULL) { + fprintf(stderr, "no memory\n"); + return NULL; + } + + weston_surface_configure(surface, 0, 0, 8192, 8192); + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); + return surface; +} + +/* + * Handle size dismatch and positioning according to the method. + */ +static void +shell_configure_fullscreen(struct shell_surface *shsurf) +{ + struct weston_output *output = shsurf->fullscreen_output; + struct weston_surface *surface = shsurf->surface; + struct weston_matrix *matrix; + float scale; + + center_on_output(surface, output); + + switch (shsurf->fullscreen.type) { + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT: + break; + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE: + matrix = &shsurf->fullscreen.transform.matrix; + weston_matrix_init(matrix); + scale = (float)output->current->width/(float)surface->geometry.width; + weston_matrix_scale(matrix, scale, scale, 1); + wl_list_remove(&shsurf->fullscreen.transform.link); + wl_list_insert(surface->geometry.transformation_list.prev, + &shsurf->fullscreen.transform.link); + weston_surface_set_position(surface, output->x, output->y); + break; + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER: + break; + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL: + break; + default: + break; + } +} + +/* + * Handle the stacking order of the fullscreen surface and the associated black surface. + */ +static void +shell_stack_fullscreen(struct shell_surface *shsurf, bool mapped) +{ + struct weston_surface *surface = shsurf->surface; + struct wl_shell *shell = shell_surface_get_shell(shsurf); + struct wl_list *list; + + if (mapped) { + wl_list_remove(&surface->link); + wl_list_remove(&shsurf->fullscreen.black_surface->link); + } + + if (shell->locked) { + wl_list_insert(&shell->hidden_surface_list, &surface->link); + wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link); + } else { + list = weston_compositor_top(surface->compositor); + wl_list_insert(list, &surface->link); + wl_list_insert(&surface->link, &shsurf->fullscreen.black_surface->link); + + /*assign output*/ + surface->output = shsurf->fullscreen_output; + shsurf->fullscreen.black_surface->output = shsurf->fullscreen_output; + if (!wl_list_empty(&surface->frame_callback_list)) { + wl_list_insert_list(surface->output->frame_callback_list.prev, + &surface->frame_callback_list); + wl_list_init(&surface->frame_callback_list); + } + + weston_compositor_repick(surface->compositor); + weston_surface_damage(surface); + weston_surface_damage(shsurf->fullscreen.black_surface); + } +} + +static void +shell_map_fullscreen(struct shell_surface *shsurf) +{ + shell_configure_fullscreen(shsurf); + shell_stack_fullscreen(shsurf, false); +} + +static void +shell_raise_fullscreen(struct shell_surface *shsurf) +{ + shell_configure_fullscreen(shsurf); + shell_stack_fullscreen(shsurf, true); +} + static void shell_surface_set_fullscreen(struct wl_client *client, struct wl_resource *resource, @@ -496,21 +625,28 @@ shell_surface_set_fullscreen(struct wl_client *client, { struct shell_surface *shsurf = resource->data; struct weston_surface *es = shsurf->surface; - struct weston_output *output; + + if (output_resource) + shsurf->output = output_resource->data; + else + shsurf->output = get_default_output(es->compositor); if (reset_shell_surface_type(shsurf)) return; - /* FIXME: Fullscreen on first output */ - /* FIXME: Handle output going away */ - output = get_default_output(es->compositor); - shsurf->saved_x = es->geometry.x; shsurf->saved_y = es->geometry.y; - shsurf->output = output; - shsurf->fullscreen_output = output; + shsurf->fullscreen_output = shsurf->output; + shsurf->fullscreen.type = method; + shsurf->fullscreen.framerate = framerate; shsurf->type = SHELL_SURFACE_FULLSCREEN; + if (shsurf->fullscreen.black_surface == NULL) + shsurf->fullscreen.black_surface = create_black_surface(es->compositor); + + if (es->output) + shsurf->surface->force_configure = 1; + wl_resource_post_event(resource, WL_SHELL_SURFACE_CONFIGURE, weston_compositor_get_time(), 0, @@ -653,6 +789,9 @@ destroy_shell_surface(struct wl_resource *resource) if (shsurf->surface) wl_list_remove(&shsurf->surface_destroy_listener.link); + if (shsurf->fullscreen.black_surface) + weston_surface_destroy(shsurf->fullscreen.black_surface); + wl_list_remove(&shsurf->link); free(shsurf); } @@ -715,7 +854,15 @@ shell_get_shell_surface(struct wl_client *client, (void (**)(void)) &shell_surface_implementation; shsurf->resource.data = shsurf; + shsurf->saved_x = INVALID_X; + shsurf->saved_y = INVALID_Y; shsurf->surface = surface; + shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; + shsurf->fullscreen.framerate = 0; + shsurf->fullscreen.black_surface = NULL; + wl_list_init(&shsurf->fullscreen.transform.link); + weston_matrix_init(&shsurf->fullscreen.transform.matrix); + shsurf->surface_destroy_listener.func = shell_handle_surface_destroy; wl_list_insert(surface->surface.resource.destroy_listener_list.prev, &shsurf->surface_destroy_listener.link); @@ -1274,6 +1421,9 @@ activate(struct weston_shell *base, struct weston_surface *es, &es->link); } break; + case SHELL_SURFACE_FULLSCREEN: + /* should on top of panels*/ + break; default: if (!shell->locked) { list = weston_compositor_top(compositor); @@ -1290,14 +1440,22 @@ activate(struct weston_shell *base, struct weston_surface *es, static void click_to_activate_binding(struct wl_input_device *device, - uint32_t time, uint32_t key, + uint32_t time, uint32_t key, uint32_t button, uint32_t state, void *data) { struct weston_input_device *wd = (struct weston_input_device *) device; struct weston_compositor *compositor = data; struct weston_surface *focus; + struct weston_surface *upper; focus = (struct weston_surface *) device->pointer_focus; + upper = container_of(focus->link.prev, struct weston_surface, link); + if (get_shell_surface_type(upper) == SHELL_SURFACE_FULLSCREEN) { + printf("%s: focus is black surface, raise its fullscreen surf\n", __func__); + shell_raise_fullscreen (get_shell_surface(upper)); + focus = upper; + } + if (state && focus && device->pointer_grab == &device->default_pointer_grab) activate(compositor->shell, focus, wd, time); } @@ -1438,9 +1596,11 @@ map(struct weston_shell *base, struct weston_surface *surface, 10 + random() % 400); break; case SHELL_SURFACE_SCREENSAVER: - case SHELL_SURFACE_FULLSCREEN: center_on_output(surface, shsurf->fullscreen_output); break; + case SHELL_SURFACE_FULLSCREEN: + shell_map_fullscreen(shsurf); + break; case SHELL_SURFACE_MAXIMIZED: /*use surface configure to set the geometry*/ panel_height = get_output_panel_height(shell,surface->output); @@ -1490,6 +1650,9 @@ map(struct weston_shell *base, struct weston_surface *surface, } do_configure = 0; break; + case SHELL_SURFACE_FULLSCREEN: + do_configure = 0; + break; case SHELL_SURFACE_NONE: do_configure = 0; break; @@ -1520,7 +1683,7 @@ map(struct weston_shell *base, struct weston_surface *surface, if (!shell->locked) activate(base, surface, (struct weston_input_device *) - compositor->input_device, + compositor->input_device, weston_compositor_get_time()); break; default: @@ -1538,6 +1701,7 @@ configure(struct weston_shell *base, struct weston_surface *surface, struct wl_shell *shell = container_of(base, struct wl_shell, shell); enum shell_surface_type surface_type = SHELL_SURFACE_NONE; struct shell_surface *shsurf; + bool do_activate = false; shsurf = get_shell_surface(surface); if (shsurf) @@ -1551,15 +1715,42 @@ configure(struct weston_shell *base, struct weston_surface *surface, switch (surface_type) { case SHELL_SURFACE_SCREENSAVER: - case SHELL_SURFACE_FULLSCREEN: center_on_output(surface, shsurf->fullscreen_output); break; + case SHELL_SURFACE_FULLSCREEN: + if (wl_list_empty(&shsurf->fullscreen.black_surface->link)) { + shell_raise_fullscreen(shsurf); + do_activate = true; + } else { + /*just do the positioning*/ + shell_configure_fullscreen(shsurf); + } + break; case SHELL_SURFACE_MAXIMIZED: /*setting x, y and using configure to change that geometry*/ surface->geometry.x = surface->output->x; surface->geometry.y = surface->output->y + get_output_panel_height(shell,surface->output); break; + case SHELL_SURFACE_TOPLEVEL: + if (!wl_list_empty(&shsurf->fullscreen.black_surface->link)) { + wl_list_remove(&surface->link); + wl_list_init(&surface->link); + weston_surface_damage_below(shsurf->fullscreen.black_surface); + wl_list_remove(&shsurf->fullscreen.black_surface->link); + wl_list_init(&shsurf->fullscreen.black_surface->link); + shsurf->fullscreen.black_surface->output = NULL; + if (shsurf->saved_x != INVALID_X && + shsurf->saved_y != INVALID_Y && + shsurf->saved_x != surface->geometry.x && + shsurf->saved_y != surface->geometry.y) { + weston_surface_set_position(surface, + shsurf->saved_x, + shsurf->saved_y); + } + do_activate = true; + } + break; default: break; } @@ -1573,6 +1764,12 @@ configure(struct weston_shell *base, struct weston_surface *surface, else if (surface_type == SHELL_SURFACE_MAXIMIZED) surface->output = shsurf->output; } + + if (do_activate && !shell->locked) + activate(surface->compositor->shell, surface, + (struct weston_input_device *) + surface->compositor->input_device, + weston_compositor_get_time()); } static int launch_desktop_shell_process(struct wl_shell *shell); -- 1.7.5.4 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel