X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fshell.c;h=c884f16e1dc34d3ea60ae418358e43aa47e36372;hb=1f888f2050ac50ec8c1750ff4f0e2c485936d7ed;hp=687094a23959915a8cfc4463509cd414dbdac3f5;hpb=831d1b21b5e786d2e5e804ca5a6a2a2b1dfacd1e;p=src%2Fagl-compositor.git diff --git a/src/shell.c b/src/shell.c index 687094a..c884f16 100644 --- a/src/shell.c +++ b/src/shell.c @@ -46,24 +46,29 @@ static void create_black_surface_view(struct ivi_output *output); static void -insert_black_surface(struct ivi_output *output); +agl_shell_desktop_advertise_application_id(struct ivi_compositor *ivi, + struct ivi_surface *surface) +{ + struct desktop_client *dclient; + + /* advertise to all desktop clients the new surface */ + wl_list_for_each(dclient, &ivi->desktop_clients, link) { + const char *app_id = + weston_desktop_surface_get_app_id(surface->dsurface); + agl_shell_desktop_send_application(dclient->resource, app_id); + } +} void ivi_set_desktop_surface(struct ivi_surface *surface) { - struct desktop_client *dclient; struct ivi_compositor *ivi = surface->ivi; assert(surface->role == IVI_SURFACE_ROLE_NONE); surface->role = IVI_SURFACE_ROLE_DESKTOP; wl_list_insert(&surface->ivi->surfaces, &surface->link); - /* advertise to all desktop clients the new surface */ - wl_list_for_each(dclient, &ivi->desktop_clients, link) { - const char *app_id = - weston_desktop_surface_get_app_id(surface->dsurface); - agl_shell_desktop_send_application(dclient->resource, app_id); - } + agl_shell_desktop_advertise_application_id(ivi, surface); } static void @@ -74,6 +79,8 @@ ivi_set_desktop_surface_popup(struct ivi_surface *surface) surface->role = IVI_SURFACE_ROLE_POPUP; wl_list_insert(&ivi->surfaces, &surface->link); + + agl_shell_desktop_advertise_application_id(ivi, surface); } static void @@ -84,8 +91,34 @@ ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface) surface->role = IVI_SURFACE_ROLE_FULLSCREEN; wl_list_insert(&ivi->surfaces, &surface->link); + + agl_shell_desktop_advertise_application_id(ivi, surface); +} + +static void +ivi_set_desktop_surface_remote(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + struct weston_view *view; + struct ivi_output *output = surface->remote.output; + + assert(surface->role == IVI_SURFACE_ROLE_NONE); + + /* remote type are the same as desktop just that client can tell + * the compositor to start on another output */ + surface->role = IVI_SURFACE_ROLE_REMOTE; + + /* if thew black surface view is mapped on the mean we need + * to remove it in order to start showing the 'remote' surface + * just being added */ + view = output->fullscreen_view.fs->view; + if (view->is_mapped || view->surface->is_mapped) + remove_black_surface(output); + + wl_list_insert(&ivi->surfaces, &surface->link); } + static void ivi_set_desktop_surface_split(struct ivi_surface *surface) { @@ -98,11 +131,14 @@ ivi_set_desktop_surface_split(struct ivi_surface *surface) surface->role = IVI_SURFACE_ROLE_SPLIT_H; wl_list_insert(&ivi->surfaces, &surface->link); + + agl_shell_desktop_advertise_application_id(ivi, surface); } static void ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, - int x, int y, const char *app_id) + int x, int y, int bx, int by, int width, int height, + const char *app_id) { struct ivi_compositor *ivi = ioutput->ivi; size_t len_app_id = strlen(app_id); @@ -115,6 +151,11 @@ ivi_set_pending_desktop_surface_popup(struct ivi_output *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; + wl_list_insert(&ivi->popup_pending_apps, &p_popup->link); } @@ -165,6 +206,24 @@ ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput, wl_list_insert(&ivi->split_pending_apps, &split->link); } +void +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)); + + remote->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + memcpy(remote->app_id, app_id, len_app_id); + + remote->ioutput = ioutput; + + wl_list_insert(&ivi->remote_pending_apps, &remote->link); +} + + static void ivi_remove_pending_desktop_surface_split(struct pending_split *split) { @@ -189,6 +248,14 @@ ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup) free(p_popup); } +static void +ivi_remove_pending_desktop_surface_remote(struct pending_remote *remote) +{ + free(remote->app_id); + wl_list_remove(&remote->link); + free(remote); +} + static bool ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) { @@ -197,7 +264,7 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) const char *_app_id = weston_desktop_surface_get_app_id(surface->dsurface); - if (wl_list_empty(&ivi->popup_pending_apps)) + if (wl_list_empty(&ivi->popup_pending_apps) || !_app_id) return false; wl_list_for_each_safe(p_popup, next_p_popup, @@ -206,6 +273,12 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) surface->popup.output = p_popup->ioutput; surface->popup.x = p_popup->x; surface->popup.y = p_popup->y; + + surface->popup.bb.x = p_popup->bb.x; + surface->popup.bb.y = p_popup->bb.y; + surface->popup.bb.width = p_popup->bb.width; + surface->popup.bb.height = p_popup->bb.height; + ivi_remove_pending_desktop_surface_popup(p_popup); return true; } @@ -222,7 +295,7 @@ ivi_check_pending_desktop_surface_split(struct ivi_surface *surface) const char *_app_id = weston_desktop_surface_get_app_id(surface->dsurface); - if (wl_list_empty(&ivi->split_pending_apps)) + if (wl_list_empty(&ivi->split_pending_apps) || !_app_id) return false; wl_list_for_each_safe(split_surf, next_split_surf, @@ -246,7 +319,7 @@ ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface) const char *_app_id = weston_desktop_surface_get_app_id(surface->dsurface); - if (wl_list_empty(&ivi->fullscreen_pending_apps)) + if (wl_list_empty(&ivi->fullscreen_pending_apps) || !_app_id) return false; wl_list_for_each_safe(fs_surf, next_fs_surf, @@ -261,6 +334,30 @@ ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface) return false; } +static bool +ivi_check_pending_desktop_surface_remote(struct ivi_surface *surface) +{ + struct pending_remote *remote_surf, *next_remote_surf; + struct ivi_compositor *ivi = surface->ivi; + const char *_app_id = + weston_desktop_surface_get_app_id(surface->dsurface); + + if (wl_list_empty(&ivi->remote_pending_apps) || !_app_id) + return false; + + wl_list_for_each_safe(remote_surf, next_remote_surf, + &ivi->remote_pending_apps, link) { + if (!strcmp(_app_id, remote_surf->app_id)) { + surface->remote.output = remote_surf->ioutput; + ivi_remove_pending_desktop_surface_remote(remote_surf); + return true; + } + } + + return false; +} + + void ivi_check_pending_desktop_surface(struct ivi_surface *surface) { @@ -269,18 +366,28 @@ ivi_check_pending_desktop_surface(struct ivi_surface *surface) ret = ivi_check_pending_desktop_surface_popup(surface); if (ret) { ivi_set_desktop_surface_popup(surface); + ivi_layout_popup_committed(surface); return; } ret = ivi_check_pending_desktop_surface_split(surface); if (ret) { ivi_set_desktop_surface_split(surface); + ivi_layout_split_committed(surface); return; } ret = ivi_check_pending_desktop_surface_fullscreen(surface); if (ret) { ivi_set_desktop_surface_fullscreen(surface); + ivi_layout_fullscreen_committed(surface); + return; + } + + ret = ivi_check_pending_desktop_surface_remote(surface); + if (ret) { + ivi_set_desktop_surface_remote(surface); + ivi_layout_desktop_committed(surface); return; } @@ -479,11 +586,19 @@ create_black_surface_view(struct ivi_output *output) &output->fullscreen_view.fs_destroy); } -static void +void remove_black_surface(struct ivi_output *output) { - struct weston_view *view = output->fullscreen_view.fs->view; + struct weston_view *view; + + if (!output && + !output->fullscreen_view.fs && + !output->fullscreen_view.fs->view) { + weston_log("Output %s doesn't have a surface installed!\n", output->name); + return; + } + view = output->fullscreen_view.fs->view; assert(view->is_mapped == true || view->surface->is_mapped == true); @@ -496,11 +611,19 @@ remove_black_surface(struct ivi_output *output) weston_output_damage(output->output); } -static void +void insert_black_surface(struct ivi_output *output) { - struct weston_view *view = output->fullscreen_view.fs->view; + struct weston_view *view; + + if (!output && + !output->fullscreen_view.fs && + !output->fullscreen_view.fs->view) { + weston_log("Output %s doesn't have a surface installed!\n", output->name); + return; + } + view = output->fullscreen_view.fs->view; if (view->is_mapped || view->surface->is_mapped) return; @@ -529,7 +652,8 @@ shell_ready(struct wl_client *client, struct wl_resource *shell_res) ivi->shell_client.ready = true; wl_list_for_each(output, &ivi->outputs, link) { - remove_black_surface(output); + if (output->background) + remove_black_surface(output); ivi_layout_init(ivi, output); } @@ -669,8 +793,7 @@ shell_set_panel(struct wl_client *client, weston_desktop_surface_set_size(dsurface, width, height); } - -static void +void shell_advertise_app_state(struct ivi_compositor *ivi, const char *app_id, const char *data, uint32_t app_state) { @@ -750,7 +873,9 @@ static void shell_desktop_set_app_property(struct wl_client *client, struct wl_resource *shell_res, const char *app_id, uint32_t role, - int x, int y, struct wl_resource *output_res) + int x, int y, int bx, int by, + int width, int height, + struct wl_resource *output_res) { struct weston_head *head = weston_head_from_resource(output_res); struct weston_output *woutput = weston_head_get_output(head); @@ -758,7 +883,8 @@ shell_desktop_set_app_property(struct wl_client *client, switch (role) { case AGL_SHELL_DESKTOP_APP_ROLE_POPUP: - ivi_set_pending_desktop_surface_popup(output, x, y, app_id); + ivi_set_pending_desktop_surface_popup(output, x, y, bx, by, + width, height, app_id); break; case AGL_SHELL_DESKTOP_APP_ROLE_FULLSCREEN: ivi_set_pending_desktop_surface_fullscreen(output, app_id); @@ -767,6 +893,9 @@ shell_desktop_set_app_property(struct wl_client *client, case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL: ivi_set_pending_desktop_surface_split(output, app_id, role); break; + case AGL_SHELL_DESKTOP_APP_ROLE_REMOTE: + ivi_set_pending_desktop_surface_remote(output, app_id); + break; default: break; } @@ -823,6 +952,17 @@ bind_agl_shell(struct wl_client *client, { struct ivi_compositor *ivi = data; struct wl_resource *resource; + struct ivi_policy *policy; + void *interface; + + policy = ivi->policy; + interface = (void *) &agl_shell_interface; + if (policy && policy->api.shell_bind_interface && + !policy->api.shell_bind_interface(client, interface)) { + wl_client_post_implementation_error(client, + "client not authorized to use agl_shell"); + return; + } resource = wl_resource_create(client, &agl_shell_interface, 1, id); @@ -865,8 +1005,20 @@ bind_agl_shell_desktop(struct wl_client *client, { struct ivi_compositor *ivi = data; struct wl_resource *resource; - struct desktop_client *dclient = zalloc(sizeof(*dclient)); + struct ivi_policy *policy; + struct desktop_client *dclient; + void *interface; + + policy = ivi->policy; + interface = (void *) &agl_shell_desktop_interface; + if (policy && policy->api.shell_bind_interface && + !policy->api.shell_bind_interface(client, interface)) { + wl_client_post_implementation_error(client, + "client not authorized to use agl_shell_desktop"); + return; + } + dclient = zalloc(sizeof(*dclient)); if (!dclient) { wl_client_post_no_memory(client); return;