X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fshell.c;h=cbe1252d0d3e743aa8609befc648f5b5dcb53104;hb=refs%2Fheads%2Fneedlefish;hp=3f528dee941e63984a677fa1db280ff51c5b35aa;hpb=5101851ecb304e75d536a7e83c92ba890d4e5e83;p=src%2Fagl-compositor.git diff --git a/src/shell.c b/src/shell.c index 3f528de..cbe1252 100644 --- a/src/shell.c +++ b/src/shell.c @@ -87,6 +87,16 @@ ivi_set_desktop_surface(struct ivi_surface *surface) agl_shell_desktop_advertise_application_id(ivi, surface); } +static void +ivi_set_background_surface(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + assert(surface->role == IVI_SURFACE_ROLE_BACKGROUND); + + wl_list_insert(&surface->ivi->surfaces, &surface->link); + agl_shell_desktop_advertise_application_id(ivi, surface); +} + static void ivi_set_desktop_surface_popup(struct ivi_surface *surface) { @@ -236,18 +246,50 @@ ivi_set_desktop_surface_split(struct ivi_surface *surface) agl_shell_desktop_advertise_application_id(ivi, surface); } +static struct pending_popup * +ivi_ensure_popup(struct ivi_output *ioutput, int x, int y, int bx, int by, + int width, int height, const char *app_id) +{ + struct pending_popup *p_popup = zalloc(sizeof(*p_popup)); + size_t len_app_id = strlen(app_id); + + if (!p_popup) + return NULL; + p_popup->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!p_popup->app_id) { + free(p_popup); + return NULL; + } + memcpy(p_popup->app_id, app_id, len_app_id); + p_popup->ioutput = ioutput; + p_popup->x = x; + p_popup->y = y; + + p_popup->bb.x = bx; + p_popup->bb.y = by; + p_popup->bb.width = width; + p_popup->bb.height = height; + + return p_popup; +} + static void -ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, - int x, int y, int bx, int by, int width, int height, - const char *app_id) +ivi_update_popup(struct ivi_output *ioutput, int x, int y, int bx, int by, + int width, int height, const char *app_id, struct pending_popup *p_popup) { - struct ivi_compositor *ivi = ioutput->ivi; size_t len_app_id = strlen(app_id); - struct pending_popup *p_popup = zalloc(sizeof(*p_popup)); + wl_list_remove(&p_popup->link); + wl_list_init(&p_popup->link); + + memset(p_popup->app_id, 0, strlen(app_id) + 1); + free(p_popup->app_id); p_popup->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!p_popup->app_id) + return; memcpy(p_popup->app_id, app_id, len_app_id); + p_popup->ioutput = ioutput; p_popup->x = x; p_popup->y = y; @@ -256,6 +298,104 @@ ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, p_popup->bb.y = by; p_popup->bb.width = width; p_popup->bb.height = height; +} + +static struct pending_fullscreen * +ivi_ensure_fullscreen(struct ivi_output *ioutput, const char *app_id) +{ + struct pending_fullscreen *p_fullscreen = zalloc(sizeof(*p_fullscreen)); + size_t len_app_id = strlen(app_id); + + if (!p_fullscreen) + return NULL; + p_fullscreen->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!p_fullscreen->app_id) { + free(p_fullscreen); + return NULL; + } + memcpy(p_fullscreen->app_id, app_id, len_app_id); + + p_fullscreen->ioutput = ioutput; + return p_fullscreen; +} + +static void +ivi_update_fullscreen(struct ivi_output *ioutput, const char *app_id, + struct pending_fullscreen *p_fullscreen) +{ + size_t len_app_id = strlen(app_id); + + wl_list_remove(&p_fullscreen->link); + wl_list_init(&p_fullscreen->link); + + memset(p_fullscreen->app_id, 0, strlen(app_id) + 1); + free(p_fullscreen->app_id); + + p_fullscreen->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!p_fullscreen->app_id) + return; + memcpy(p_fullscreen->app_id, app_id, len_app_id); + + p_fullscreen->ioutput = ioutput; +} + +static struct pending_remote * +ivi_ensure_remote(struct ivi_output *ioutput, const char *app_id) +{ + struct pending_remote *p_remote = zalloc(sizeof(*p_remote)); + size_t len_app_id = strlen(app_id); + + if (!p_remote) + return NULL; + p_remote->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!p_remote->app_id) { + free(p_remote); + return NULL; + } + memcpy(p_remote->app_id, app_id, len_app_id); + + p_remote->ioutput = ioutput; + return p_remote; +} + +static void +ivi_update_remote(struct ivi_output *ioutput, const char *app_id, + struct pending_remote *p_remote) +{ + size_t len_app_id = strlen(app_id); + + wl_list_remove(&p_remote->link); + wl_list_init(&p_remote->link); + + memset(p_remote->app_id, 0, strlen(app_id) + 1); + free(p_remote->app_id); + + p_remote->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!p_remote->app_id) + return; + memcpy(p_remote->app_id, app_id, len_app_id); + + p_remote->ioutput = ioutput; +} + +static void +ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, int x, int y, int bx, + int by, int width, int height, const char *app_id) +{ + struct ivi_compositor *ivi = ioutput->ivi; + struct pending_popup *p_popup = NULL; + struct pending_popup *popup; + + wl_list_for_each(popup, &ivi->popup_pending_apps, link) + if (!strcmp(app_id, popup->app_id)) + p_popup = popup; + + if (!p_popup) + p_popup = ivi_ensure_popup(ioutput, x, y, bx, by, width, height, app_id); + else + ivi_update_popup(ioutput, x, y, bx, by, width, height, app_id, p_popup); + if (!p_popup) + return; wl_list_insert(&ivi->popup_pending_apps, &p_popup->link); } @@ -265,16 +405,21 @@ ivi_set_pending_desktop_surface_fullscreen(struct ivi_output *ioutput, const char *app_id) { struct ivi_compositor *ivi = ioutput->ivi; - size_t len_app_id = strlen(app_id); - - struct pending_fullscreen *fs = zalloc(sizeof(*fs)); + struct pending_fullscreen *p_fullscreen = NULL; + struct pending_fullscreen *fullscreen; - fs->app_id = zalloc(sizeof(char) * (len_app_id + 1)); - memcpy(fs->app_id, app_id, len_app_id); + wl_list_for_each(fullscreen, &ivi->fullscreen_pending_apps, link) + if (!strcmp(app_id, fullscreen->app_id)) + p_fullscreen = fullscreen; - fs->ioutput = ioutput; + if (!p_fullscreen) + p_fullscreen = ivi_ensure_fullscreen(ioutput, app_id); + else + ivi_update_fullscreen(ioutput, app_id, p_fullscreen); - wl_list_insert(&ivi->fullscreen_pending_apps, &fs->link); + if (!p_fullscreen) + return; + wl_list_insert(&ivi->fullscreen_pending_apps, &p_fullscreen->link); } static void @@ -298,7 +443,13 @@ ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput, return; split = zalloc(sizeof(*split)); + if (!split) + return; split->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + if (!split->app_id) { + free(split); + return; + } memcpy(split->app_id, app_id, len_app_id); split->ioutput = ioutput; @@ -312,16 +463,21 @@ ivi_set_pending_desktop_surface_remote(struct ivi_output *ioutput, const char *app_id) { struct ivi_compositor *ivi = ioutput->ivi; - size_t len_app_id = strlen(app_id); - - struct pending_remote *remote = zalloc(sizeof(*remote)); + struct pending_remote *remote; + struct pending_remote *p_remote = NULL; - remote->app_id = zalloc(sizeof(char) * (len_app_id + 1)); - memcpy(remote->app_id, app_id, len_app_id); + wl_list_for_each(remote, &ivi->remote_pending_apps, link) + if (!strcmp(app_id, remote->app_id)) + p_remote = remote; - remote->ioutput = ioutput; + if (!p_remote) + p_remote = ivi_ensure_remote(ioutput, app_id); + else + ivi_update_remote(ioutput, app_id, p_remote); + if (!p_remote) + return; - wl_list_insert(&ivi->remote_pending_apps, &remote->link); + wl_list_insert(&ivi->remote_pending_apps, &p_remote->link); } @@ -467,9 +623,9 @@ ivi_check_pending_desktop_surface_remote(struct ivi_surface *surface) return false; } - -bool -ivi_check_pending_surface(struct ivi_surface *surface) +void +ivi_check_pending_surface_desktop(struct ivi_surface *surface, + enum ivi_surface_role *role) { struct ivi_compositor *ivi = surface->ivi; struct wl_list *role_pending_list; @@ -480,39 +636,40 @@ ivi_check_pending_surface(struct ivi_surface *surface) const char *app_id = weston_desktop_surface_get_app_id(surface->dsurface); - if (!app_id) - return false; - role_pending_list = &ivi->popup_pending_apps; wl_list_for_each(p_popup, role_pending_list, link) { - if (!strcmp(app_id, p_popup->app_id)) { - return true; + if (app_id && !strcmp(app_id, p_popup->app_id)) { + *role = IVI_SURFACE_ROLE_POPUP; + return; } } role_pending_list = &ivi->split_pending_apps; wl_list_for_each(p_split, role_pending_list, link) { - if (!strcmp(app_id, p_split->app_id)) { - return true; + if (app_id && !strcmp(app_id, p_split->app_id)) { + *role = IVI_SURFACE_ROLE_SPLIT_V; + return; } } role_pending_list = &ivi->fullscreen_pending_apps; wl_list_for_each(p_fullscreen, role_pending_list, link) { - if (!strcmp(app_id, p_fullscreen->app_id)) { - return true; + if (app_id && !strcmp(app_id, p_fullscreen->app_id)) { + *role = IVI_SURFACE_ROLE_FULLSCREEN; + return; } } role_pending_list = &ivi->remote_pending_apps; wl_list_for_each(p_remote, role_pending_list, link) { - if (!strcmp(app_id, p_remote->app_id)) { - return true; + if (app_id && !strcmp(app_id, p_remote->app_id)) { + *role = IVI_SURFACE_ROLE_REMOTE; + return; } } /* else, we are a regular desktop surface */ - return false; + *role = IVI_SURFACE_ROLE_DESKTOP; } @@ -592,6 +749,63 @@ ivi_shell_init(struct ivi_compositor *ivi) return 0; } + +static void +ivi_surf_destroy(struct ivi_surface *surf) +{ + struct weston_surface *wsurface = surf->view->surface; + + if (weston_surface_is_mapped(wsurface)) { + weston_desktop_surface_unlink_view(surf->view); + weston_view_destroy(surf->view); + } + + wl_list_remove(&surf->link); + free(surf); +} + +static void +ivi_shell_destroy_views_on_layer(struct weston_layer *layer) +{ + struct weston_view *view, *view_next; + + wl_list_for_each_safe(view, view_next, &layer->view_list.link, layer_link.link) { + struct ivi_surface *ivi_surf = + get_ivi_shell_surface(view->surface); + if (ivi_surf) + ivi_surf_destroy(ivi_surf); + } +} + +void +ivi_shell_finalize(struct ivi_compositor *ivi) +{ + struct ivi_output *output; + + ivi_shell_destroy_views_on_layer(&ivi->hidden); + weston_layer_fini(&ivi->hidden); + + ivi_shell_destroy_views_on_layer(&ivi->background); + weston_layer_fini(&ivi->background); + + ivi_shell_destroy_views_on_layer(&ivi->normal); + weston_layer_fini(&ivi->normal); + + ivi_shell_destroy_views_on_layer(&ivi->panel); + weston_layer_fini(&ivi->panel); + + ivi_shell_destroy_views_on_layer(&ivi->popup); + weston_layer_fini(&ivi->popup); + + wl_list_for_each(output, &ivi->outputs, link) { + if (output->fullscreen_view.fs->view) { + weston_surface_destroy(output->fullscreen_view.fs->view->surface); + output->fullscreen_view.fs->view = NULL; + } + } + weston_layer_fini(&ivi->fullscreen); +} + static void ivi_shell_advertise_xdg_surfaces(struct ivi_compositor *ivi, struct wl_resource *resource) { @@ -730,15 +944,23 @@ create_black_surface_view(struct ivi_output *output) return; surface = weston_surface_create(wc); + if (!surface) + return; view = weston_view_create(surface); - - assert(view || surface); + if (!view) { + weston_surface_destroy(surface); + return; + } weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); weston_surface_set_size(surface, woutput->width, woutput->height); weston_view_set_position(view, woutput->x, woutput->y); output->fullscreen_view.fs = zalloc(sizeof(struct ivi_surface)); + if (!output->fullscreen_view.fs) { + weston_surface_destroy(surface); + return; + } output->fullscreen_view.fs->view = view; output->fullscreen_view.fs_destroy.notify = destroy_black_view; @@ -812,8 +1034,14 @@ shell_ready(struct wl_client *client, struct wl_resource *shell_res) ivi->shell_client.ready = true; wl_list_for_each(output, &ivi->outputs, link) { - if (output->background) + if (output->background && + output->background->role == IVI_SURFACE_ROLE_BACKGROUND) { + /* track the background surface role as a "regular" + * surface so we can activate it */ + ivi_set_background_surface(output->background); remove_black_surface(output); + } + ivi_layout_init(ivi, output); } @@ -1068,7 +1296,7 @@ shell_desktop_set_app_property(struct wl_client *client, } } -static void +void ivi_compositor_destroy_pending_surfaces(struct ivi_compositor *ivi) { struct pending_popup *p_popup, *next_p_popup; @@ -1178,14 +1406,6 @@ bind_agl_shell(struct wl_client *client, return; } -#if 0 - if (ivi->shell_client.client != client) { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "client not authorized to use agl_shell"); - return; - } -#endif - if (ivi->shell_client.resource) { wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "agl_shell has already been bound");