X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fshell.c;h=2b6bd63f8e09dd9c64693a21f9001d70fd74f40e;hb=699bdf5e69517f2e7d7238377b41121b1470af3f;hp=ac20b4fcb942ee1278fb291946aa8623e7834854;hpb=b80044887e97509433eb19945ce8feab68151044;p=src%2Fagl-compositor.git diff --git a/src/shell.c b/src/shell.c index ac20b4f..2b6bd63 100644 --- a/src/shell.c +++ b/src/shell.c @@ -46,10 +46,6 @@ #include "agl-shell-server-protocol.h" #include "agl-shell-desktop-server-protocol.h" -#ifdef HAVE_WALTHAM -#include -#endif - static void create_black_curtain_view(struct ivi_output *output); @@ -125,88 +121,6 @@ ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface) agl_shell_desktop_advertise_application_id(ivi, surface); } -#ifdef HAVE_WALTHAM -void -ivi_destroy_waltham_destroy(struct ivi_surface *surface) -{ - struct ivi_compositor *ivi = surface->ivi; - const struct weston_transmitter_api *api = - ivi->waltham_transmitter_api; - - if (!api) - return; - - if (surface->waltham_surface.transmitter_surface) - api->surface_destroy(surface->waltham_surface.transmitter_surface); -} - -static void -ivi_output_notify_waltham_plugin(struct ivi_surface *surface) -{ - struct ivi_compositor *ivi = surface->ivi; - const struct weston_transmitter_api *api = ivi->waltham_transmitter_api; - struct weston_transmitter *transmitter; - struct weston_transmitter_remote *trans_remote; - struct weston_surface *weston_surface; - struct weston_output *woutput = surface->remote.output->output; - const char *app_id; - - if (!api) - return; - - transmitter = api->transmitter_get(ivi->compositor); - if (!transmitter) - return; - - trans_remote = api->get_transmitter_remote(woutput->name, transmitter); - if (!trans_remote) { - weston_log("Could not find a valie weston_transmitter_remote " - "that matches the output %s\n", woutput->name); - return; - } - - app_id = weston_desktop_surface_get_app_id(surface->dsurface); - weston_surface = - weston_desktop_surface_get_surface(surface->dsurface); - - weston_log("Forwarding app_id %s to remote %s\n", app_id, woutput->name); - - /* this will have the effect of informing the remote side to create a - * surface with the name app_id. W/ xdg-shell the following happens: - * - * compositor (server): - * surface_push_to_remote(): - * waltham-transmitter plug-in - * -> wthp_ivi_app_id_surface_create() - * - * client -- on the receiver side: - * -> wthp_ivi_app_id_surface_create() - * -> wth_receiver_weston_main() - * -> wl_compositor_create_surface() - * -> xdg_wm_base_get_xdg_surface - * -> xdg_toplevel_set_app_id() - * -> gst_init() - * -> gst_parse_launch() - * - * wth_receiver_weston_main() will be invoked from the handler of - * wthp_ivi_app_id_surface_create() and is responsible for setting-up - * the gstreamer pipeline as well. - */ - surface->waltham_surface.transmitter_surface = - api->surface_push_to_remote(weston_surface, app_id, trans_remote, NULL); -} - -#else -void -ivi_destroy_waltham_destroy(struct ivi_surface *surface) -{ -} -static void -ivi_output_notify_waltham_plugin(struct ivi_surface *surface) -{ -} -#endif - static void ivi_set_desktop_surface_remote(struct ivi_surface *surface) { @@ -227,9 +141,6 @@ ivi_set_desktop_surface_remote(struct ivi_surface *surface) if (view->is_mapped || view->surface->is_mapped) remove_black_curtain(output); - if (output->type == OUTPUT_WALTHAM) - ivi_output_notify_waltham_plugin(surface); - wl_list_insert(&ivi->surfaces, &surface->link); } @@ -1197,8 +1108,8 @@ shell_ready(struct wl_client *client, struct wl_resource *shell_res) ivi->shell_client.status == BOUND_FAILED) { wl_resource_post_error(shell_res, WL_DISPLAY_ERROR_INVALID_OBJECT, - "agl_shell has already been bound. " - "Check out bound_fail event"); + "agl_shell (ready quest) has already " + "been bound. Check out bound_fail event"); return; } @@ -1254,8 +1165,8 @@ shell_set_background(struct wl_client *client, ivi->shell_client.resource_ext == shell_res) { wl_resource_post_error(shell_res, WL_DISPLAY_ERROR_INVALID_OBJECT, - "agl_shell has already been bound. " - "Check out bound_fail event"); + "agl_shell (set_background) has already " + "been bound. Check out bound_fail event"); return; } @@ -1319,7 +1230,7 @@ shell_set_panel(struct wl_client *client, ivi->shell_client.resource_ext == shell_res) { wl_resource_post_error(shell_res, WL_DISPLAY_ERROR_INVALID_OBJECT, - "agl_shell has already been bound. " + "agl_shell (set_panel) has already been bound. " "Check out bound_fail event"); return; } @@ -1711,20 +1622,85 @@ shell_set_app_output(struct wl_client *client, struct wl_resource *res, struct weston_output *woutput = weston_head_get_output(head); struct ivi_output *ioutput = to_ivi_output(woutput); struct ivi_surface *surf = ivi_find_app(ivi, app_id); + struct ivi_output *desktop_last_output; + struct ivi_output *current_completed_output; if (!app_id || !ioutput) return; - if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_REMOTE)) { + /* handle the case we're not mapped at all */ + if (!surf) { ivi_set_pending_desktop_surface_remote(ioutput, app_id); shell_send_app_on_output(ivi, app_id, woutput->name); return; } + + desktop_last_output = surf->desktop.last_output; + current_completed_output = surf->current_completed_output; + + if (surf->remote.output) + surf->hidden_layer_output = surf->remote.output; + else + surf->hidden_layer_output = desktop_last_output; + assert(surf->hidden_layer_output); + + if (ivi_surface_count_one(current_completed_output, IVI_SURFACE_ROLE_REMOTE) || + ivi_surface_count_one(current_completed_output, IVI_SURFACE_ROLE_DESKTOP)) { + if (!current_completed_output->background) + insert_black_curtain(current_completed_output); + } else { + ivi_layout_deactivate(ivi, app_id); + } + + /* update the remote output */ + surf->remote.output = ioutput; + + if (surf->role != IVI_SURFACE_ROLE_REMOTE) { + wl_list_remove(&surf->link); + wl_list_init(&surf->link); + + surf->role = IVI_SURFACE_ROLE_NONE; + ivi_set_desktop_surface_remote(surf); + } + + shell_send_app_on_output(ivi, app_id, woutput->name); +} + +static void +shell_set_app_position(struct wl_client *client, struct wl_resource *res, + const char *app_id, int32_t x, int32_t y) +{ + struct ivi_compositor *ivi = wl_resource_get_user_data(res); + struct ivi_surface *surf = ivi_find_app(ivi, app_id); + + if (!surf || !app_id || surf->role != IVI_SURFACE_ROLE_POPUP) + return; + + weston_view_set_position(surf->view, x, y); + weston_compositor_schedule_repaint(ivi->compositor); +} + +static void +shell_set_app_scale(struct wl_client *client, struct wl_resource *res, + const char *app_id, int32_t width, int32_t height) +{ + + struct ivi_compositor *ivi = wl_resource_get_user_data(res); + struct ivi_surface *surf = ivi_find_app(ivi, app_id); + + if (!surf || !app_id || surf->role != IVI_SURFACE_ROLE_POPUP) + return; + + weston_desktop_surface_set_size(surf->dsurface, width, height); + weston_compositor_schedule_repaint(ivi->compositor); } static void shell_ext_destroy(struct wl_client *client, struct wl_resource *res) { + struct ivi_compositor *ivi = wl_resource_get_user_data(res); + + ivi->shell_client_ext.doas_requested = false; wl_resource_destroy(res); } @@ -1734,8 +1710,17 @@ shell_ext_doas(struct wl_client *client, struct wl_resource *res) struct ivi_compositor *ivi = wl_resource_get_user_data(res); ivi->shell_client_ext.doas_requested = true; - agl_shell_ext_send_doas_done(ivi->shell_client_ext.resource, - AGL_SHELL_EXT_DOAS_SHELL_CLIENT_STATUS_SUCCESS); + + if (ivi->shell_client_ext.resource && ivi->shell_client.resource) { + ivi->shell_client_ext.doas_requested_pending_bind = true; + + agl_shell_ext_send_doas_done(ivi->shell_client_ext.resource, + AGL_SHELL_EXT_DOAS_SHELL_CLIENT_STATUS_SUCCESS); + } else { + agl_shell_ext_send_doas_done(ivi->shell_client_ext.resource, + AGL_SHELL_EXT_DOAS_SHELL_CLIENT_STATUS_FAILED); + } + } static const struct agl_shell_interface agl_shell_implementation = { @@ -1750,6 +1735,8 @@ static const struct agl_shell_interface agl_shell_implementation = { .set_app_normal = shell_set_app_normal, .set_app_fullscreen = shell_set_app_fullscreen, .set_app_output = shell_set_app_output, + .set_app_position = shell_set_app_position, + .set_app_scale = shell_set_app_scale, }; static const struct agl_shell_ext_interface agl_shell_ext_implementation = { @@ -1853,18 +1840,20 @@ unbind_agl_shell(struct wl_resource *resource) } wl_list_for_each(output, &ivi->outputs, link) { - struct weston_geometry area = {}; /* reset the active surf if there's one present */ if (output->active) { + struct weston_geometry area = {}; + output->active->view->is_mapped = false; output->active->view->surface->is_mapped = false; weston_layer_entry_remove(&output->active->view->layer_link); output->active = NULL; + + output->area_activation = area; } - output->area_activation = area; insert_black_curtain(output); } @@ -1883,6 +1872,7 @@ unbind_agl_shell(struct wl_resource *resource) ivi->shell_client.ready = false; ivi->shell_client.resource = NULL; + ivi->shell_client.resource_ext = NULL; ivi->shell_client.client = NULL; } @@ -1892,6 +1882,8 @@ unbind_agl_shell_ext(struct wl_resource *resource) struct ivi_compositor *ivi = wl_resource_get_user_data(resource); ivi->shell_client_ext.resource = NULL; + ivi->shell_client.resource_ext = NULL; + ivi->shell_client_ext.doas_requested = false; } static void @@ -1918,54 +1910,55 @@ bind_agl_shell(struct wl_client *client, return; } - if (ivi->shell_client.resource) { - if (wl_resource_get_version(resource) == 1) { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "agl_shell has already been bound"); - return; - } - - if (ivi->shell_client_ext.resource && - ivi->shell_client_ext.doas_requested) { - - /* reset status in case client-ext doesn't send an - * explicit agl_shell_destroy request, see - * shell_destroy() */ - if (ivi->shell_client.status == BOUND_FAILED) - ivi->shell_client.status = BOUND_OK; + if (ivi->shell_client.resource && wl_resource_get_version(resource) == 1) { + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "agl_shell has already been bound (version 1)"); + wl_resource_destroy(resource); + return; + } - wl_resource_set_implementation(resource, &agl_shell_implementation, - ivi, NULL); - ivi->shell_client.resource_ext = resource; + // for agl_shell client proxy + if (ivi->shell_client.resource && + ivi->shell_client_ext.doas_requested_pending_bind) { - ivi->shell_client_ext.status = BOUND_OK; - agl_shell_send_bound_ok(ivi->shell_client.resource_ext); + ivi->shell_client_ext.doas_requested_pending_bind = false; - return; - } else { - wl_resource_set_implementation(resource, &agl_shell_implementation, - ivi, NULL); - agl_shell_send_bound_fail(resource); - ivi->shell_client.status = BOUND_FAILED; + // if there's one connected + if (ivi->shell_client.resource_ext) { + ivi->shell_client_ext.status = BOUND_FAILED; + agl_shell_send_bound_fail(ivi->shell_client.resource_ext); + wl_resource_destroy(resource); return; } + + wl_resource_set_implementation(resource, &agl_shell_implementation, + ivi, NULL); + ivi->shell_client.resource_ext = resource; + ivi->shell_client_ext.status = BOUND_OK; + agl_shell_send_bound_ok(ivi->shell_client.resource_ext); + return; + } + + + // if we already have an agl_shell client + if (ivi->shell_client.resource) { + agl_shell_send_bound_fail(resource); + ivi->shell_client.status = BOUND_FAILED; + wl_resource_destroy(resource); + return; } + // default agl_shell client + wl_resource_set_implementation(resource, &agl_shell_implementation, + ivi, unbind_agl_shell); + ivi->shell_client.resource = resource; if (wl_resource_get_version(resource) >= AGL_SHELL_BOUND_OK_SINCE_VERSION) { - wl_resource_set_implementation(resource, &agl_shell_implementation, - ivi, unbind_agl_shell); - ivi->shell_client.resource = resource; /* if we land here we'll have BOUND_OK by default, but still do the assignment */ ivi->shell_client.status = BOUND_OK; agl_shell_send_bound_ok(ivi->shell_client.resource); - } else { - /* fallback for just version 1 of the protocol */ - wl_resource_set_implementation(resource, &agl_shell_implementation, - ivi, unbind_agl_shell); - ivi->shell_client.resource = resource; } } @@ -2049,7 +2042,7 @@ int ivi_shell_create_global(struct ivi_compositor *ivi) { ivi->agl_shell = wl_global_create(ivi->compositor->wl_display, - &agl_shell_interface, 8, + &agl_shell_interface, 10, ivi, bind_agl_shell); if (!ivi->agl_shell) { weston_log("Failed to create wayland global.\n");