X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fshell.c;h=13c03f005fe344fe085ec7aece9815738f0a7071;hb=b87f46acc5b0b252e4642f2130ef3093294afac8;hp=bcfb673d3b48c0ea7c5717b67835627f1ba8d6d8;hpb=ee50083d93869aaa581a092c522efe08252fae55;p=src%2Fagl-compositor.git diff --git a/src/shell.c b/src/shell.c index bcfb673..13c03f0 100644 --- a/src/shell.c +++ b/src/shell.c @@ -38,7 +38,7 @@ #include #include -#include +#include #include "shared/os-compatibility.h" #include "shared/helpers.h" #include "shared/process-util.h" @@ -46,13 +46,12 @@ #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); +static uint32_t +reverse_orientation(uint32_t orientation); + void agl_shell_desktop_advertise_application_id(struct ivi_compositor *ivi, struct ivi_surface *surface) @@ -125,88 +124,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 +144,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); } @@ -676,6 +590,24 @@ ivi_check_pending_surface_desktop(struct ivi_surface *surface, *role = IVI_SURFACE_ROLE_DESKTOP; } +struct pending_app * +ivi_check_pending_app_type(struct ivi_surface *surface, enum ivi_surface_role role) +{ + struct pending_app *papp; + const char *app_id = NULL; + + app_id = weston_desktop_surface_get_app_id(surface->dsurface); + if (!app_id) + return NULL; + + wl_list_for_each(papp, &surface->ivi->pending_apps, link) { + if (strcmp(app_id, papp->app_id) == 0 && papp->role == role) + return papp; + } + + return NULL; +} + void ivi_check_pending_desktop_surface(struct ivi_surface *surface) @@ -706,7 +638,35 @@ ivi_check_pending_desktop_surface(struct ivi_surface *surface) ret = ivi_check_pending_desktop_surface_remote(surface); if (ret) { ivi_set_desktop_surface_remote(surface); - ivi_layout_desktop_committed(surface); + ivi_layout_remote_committed(surface); + return; + } + + /* new way of doing it */ + struct pending_app *papp = + ivi_check_pending_app_type(surface, IVI_SURFACE_ROLE_TILE); + if (papp) { + struct pending_app_tile *papp_tile = + container_of(papp, struct pending_app_tile, base); + + // handle the currently active surface + if (papp->ioutput->active) { + _ivi_set_shell_surface_split(papp->ioutput->active, NULL, + reverse_orientation(papp_tile->orientation), false); + } + + surface->role = IVI_SURFACE_ROLE_TILE; + surface->current_completed_output = papp->ioutput; + wl_list_insert(&surface->ivi->surfaces, &surface->link); + + _ivi_set_shell_surface_split(surface, papp->ioutput, + papp_tile->orientation, true); + + /* remove it from pending */ + wl_list_remove(&papp->link); + free(papp->app_id); + free(papp); + return; } @@ -1168,6 +1128,23 @@ shell_send_app_state(struct ivi_compositor *ivi, const char *app_id, } } +void +shell_send_app_on_output(struct ivi_compositor *ivi, const char *app_id, + const char *output_name) +{ + if (app_id && ivi->shell_client.resource && + wl_resource_get_version(ivi->shell_client.resource) >= + AGL_SHELL_APP_ON_OUTPUT_SINCE_VERSION) { + + agl_shell_send_app_on_output(ivi->shell_client.resource, + app_id, output_name); + + if (ivi->shell_client.resource_ext) + agl_shell_send_app_on_output(ivi->shell_client.resource_ext, + app_id, output_name); + } +} + static void shell_ready(struct wl_client *client, struct wl_resource *shell_res) { @@ -1180,8 +1157,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; } @@ -1237,8 +1214,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; } @@ -1302,7 +1279,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; } @@ -1438,6 +1415,195 @@ shell_activate_app(struct wl_client *client, ivi_layout_activate(output, app_id); } +static void +shell_new_deactivate_app(struct wl_client *client, struct wl_resource *shell_res, + const char *app_id) +{ + struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res); + + ivi_layout_deactivate(ivi, app_id); +} + +static void +shell_set_app_float(struct wl_client *client, struct wl_resource *shell_res, + const char *app_id, int32_t x_pos, int32_t y_pos) +{ + struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res); + struct weston_output *output = get_focused_output(ivi->compositor); + struct ivi_output *ivi_output; + struct ivi_surface *surf = ivi_find_app(ivi, app_id); + + if (!output) + output = get_default_output(ivi->compositor); + + ivi_output = to_ivi_output(output); + + /* verify if already mapped as desktop role, regular, unmap it, so we + * can make it float */ + if (surf && surf->role == IVI_SURFACE_ROLE_DESKTOP) { + struct weston_view *ev = surf->view; + struct weston_desktop_surface *dsurf = surf->dsurface; + struct ivi_bounding_box bb = {}; + const char *prev_activate_app_id = NULL; + + /* XXX: if this is useful we could bring it as active then make + * it float, but avoid doing it for the moment */ + if (surf != ivi_output->active) + return; + + if (ivi_output->previous_active) + prev_activate_app_id = + weston_desktop_surface_get_app_id(ivi_output->previous_active->dsurface); + + /* only deactivate if previous_active is different, otherwise + * this will blow up, because we're trying to activate the same + * app_id as the this one! */ + if (prev_activate_app_id && strcmp(app_id, prev_activate_app_id)) { + ivi_layout_deactivate(ivi, app_id); + } else if (prev_activate_app_id) { + weston_layer_entry_remove(&ev->layer_link); + weston_view_geometry_dirty(ev); + weston_surface_damage(ev->surface); + } + + surf->hidden_layer_output = ivi_output; + + /* set attributes */ + surf->popup.output = ivi_output; + + surf->popup.x = x_pos; + surf->popup.y = y_pos; + surf->popup.bb = bb; + + + /* change the role */ + surf->role = IVI_SURFACE_ROLE_NONE; + + wl_list_remove(&surf->link); + wl_list_init(&surf->link); + + ivi_set_desktop_surface_popup(surf); + + weston_desktop_surface_set_maximized(dsurf, false); + weston_desktop_surface_set_size(dsurf, 0, 0); + + /* add to hidden layer */ + weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link); + weston_compositor_schedule_repaint(ivi->compositor); + + } else if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_POPUP)) { + ivi_set_pending_desktop_surface_popup(ivi_output, x_pos, y_pos, + 0, 0, 0, 0, app_id); + } +} + +static void +shell_set_app_fullscreen(struct wl_client *client, + struct wl_resource *shell_res, const char *app_id) +{ + struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res); + struct weston_output *output = get_focused_output(ivi->compositor); + struct ivi_output *ivi_output; + struct ivi_surface *surf = ivi_find_app(ivi, app_id); + + if (!output) + output = get_default_output(ivi->compositor); + + ivi_output = to_ivi_output(output); + + if (surf && surf->role == IVI_SURFACE_ROLE_DESKTOP) { + struct weston_view *ev = surf->view; + struct weston_desktop_surface *dsurf = surf->dsurface; + + if (surf != ivi_output->active) + return; + + weston_layer_entry_remove(&surf->view->layer_link); + weston_view_geometry_dirty(surf->view); + weston_surface_damage(surf->view->surface); + + surf->hidden_layer_output = ivi_output; + + /* set attributes */ + surf->fullscreen.output = ivi_output; + + /* change the role */ + surf->role = IVI_SURFACE_ROLE_NONE; + + wl_list_remove(&surf->link); + wl_list_init(&surf->link); + + ivi_set_desktop_surface_fullscreen(surf); + + weston_desktop_surface_set_maximized(dsurf, false); + weston_desktop_surface_set_fullscreen(dsurf, true); + weston_desktop_surface_set_size(dsurf, + ivi_output->output->width, + ivi_output->output->height); + + /* add to hidden layer */ + weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link); + weston_compositor_schedule_repaint(ivi->compositor); + } else if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_FULLSCREEN)) { + ivi_set_pending_desktop_surface_fullscreen(ivi_output, app_id); + } +} + + +static void +shell_set_app_normal(struct wl_client *client, struct wl_resource *shell_res, + const char *app_id) +{ + struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res); + struct ivi_surface *surf = ivi_find_app(ivi, app_id); + struct weston_output *output = get_focused_output(ivi->compositor); + struct ivi_output *ivi_output; + struct weston_desktop_surface *dsurf; + struct weston_geometry area = {}; + + + if (!surf || (surf && surf->role == IVI_SURFACE_ROLE_DESKTOP)) + return; + + if (!output) + output = get_default_output(ivi->compositor); + + dsurf = surf->dsurface; + ivi_output = to_ivi_output(output); + + weston_layer_entry_remove(&surf->view->layer_link); + weston_view_geometry_dirty(surf->view); + weston_surface_damage(surf->view->surface); + + /* change the role */ + surf->role = IVI_SURFACE_ROLE_NONE; + surf->state = NORMAL; + surf->desktop.pending_output = ivi_output; + + wl_list_remove(&surf->link); + wl_list_init(&surf->link); + + ivi_set_desktop_surface(surf); + + if (ivi_output->area_activation.width || + ivi_output->area_activation.height) + area = ivi_output->area_activation; + else + area = ivi_output->area; + + if (weston_desktop_surface_get_fullscreen(dsurf)) + weston_desktop_surface_set_fullscreen(dsurf, false); + + weston_desktop_surface_set_maximized(dsurf, true); + weston_desktop_surface_set_size(dsurf, area.width, area.height); + + /* add to hidden layer */ + weston_layer_entry_insert(&ivi->hidden.view_list, + &surf->view->layer_link); + weston_compositor_schedule_repaint(ivi->compositor); + +} + static void shell_desktop_activate_app(struct wl_client *client, struct wl_resource *shell_res, @@ -1496,9 +1662,299 @@ shell_set_activate_region(struct wl_client *client, struct wl_resource *res, ioutput->area_activation = area; } +static void +shell_set_app_output(struct wl_client *client, struct wl_resource *res, + const char *app_id, struct wl_resource *output) +{ + struct ivi_compositor *ivi = wl_resource_get_user_data(res); + struct weston_head *head = weston_head_from_resource(output); + 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; + + /* 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 +_ivi_set_pending_desktop_surface_split(struct wl_resource *output, + const char *app_id, uint32_t orientation) +{ + weston_log("%s() added split surface for app_id '%s' with " + "orientation %d to pending\n", __func__, app_id, orientation); + + struct weston_head *head = weston_head_from_resource(output); + struct weston_output *woutput = weston_head_get_output(head); + struct ivi_output *ivi_output = to_ivi_output(woutput); + + struct pending_app_tile *app_tile = zalloc(sizeof(*app_tile)); + + app_tile->base.app_id = strdup(app_id); + app_tile->base.ioutput = ivi_output; + app_tile->base.role = IVI_SURFACE_ROLE_TILE; + + app_tile->orientation = orientation; + wl_list_insert(&ivi_output->ivi->pending_apps, &app_tile->base.link); +} + + +static uint32_t +reverse_orientation(uint32_t orientation) +{ + + switch (orientation) { + case AGL_SHELL_TILE_ORIENTATION_LEFT: + return AGL_SHELL_TILE_ORIENTATION_RIGHT; + break; + case AGL_SHELL_TILE_ORIENTATION_RIGHT: + return AGL_SHELL_TILE_ORIENTATION_LEFT; + break; + case AGL_SHELL_TILE_ORIENTATION_TOP: + return AGL_SHELL_TILE_ORIENTATION_BOTTOM; + break; + case AGL_SHELL_TILE_ORIENTATION_BOTTOM: + return AGL_SHELL_TILE_ORIENTATION_TOP; + break; + default: + return AGL_SHELL_TILE_ORIENTATION_NONE; + } +} + +void +_ivi_set_shell_surface_split(struct ivi_surface *surface, struct ivi_output *ioutput, + uint32_t orientation, bool to_activate) +{ + struct ivi_compositor *ivi = surface->ivi; + struct weston_geometry geom = {}; + struct ivi_output *output = NULL; + + int width, height; + int x, y; + + geom = weston_desktop_surface_get_geometry(surface->dsurface); + output = ivi_layout_get_output_from_surface(surface); + + if (!output) + output = ioutput; + + width = output->area.width; + height = output->area.height; + + switch (orientation) { + case AGL_SHELL_TILE_ORIENTATION_LEFT: + case AGL_SHELL_TILE_ORIENTATION_RIGHT: + width /= 2; + break; + case AGL_SHELL_TILE_ORIENTATION_TOP: + case AGL_SHELL_TILE_ORIENTATION_BOTTOM: + height /= 2; + break; + case AGL_SHELL_TILE_ORIENTATION_NONE: + break; + default: + /* nothing */ + assert(!"Invalid orientation passed"); + + } + + x = output->area.x - geom.x; + y = output->area.y - geom.y; + + if (orientation == AGL_SHELL_TILE_ORIENTATION_RIGHT) + x += width; + else if (orientation == AGL_SHELL_TILE_ORIENTATION_BOTTOM) + y += height; + + if (to_activate) { + struct weston_view *ev = surface->view; + struct ivi_shell_seat *ivi_seat = NULL; + struct weston_seat *wseat = get_ivi_shell_weston_first_seat(ivi); + + if (wseat) + ivi_seat = get_ivi_shell_seat(wseat); + + if (!weston_view_is_mapped(ev)) + weston_view_update_transform(ev); + else + weston_layer_entry_remove(&ev->layer_link); + + + // mark view as mapped + ev->is_mapped = true; + ev->surface->is_mapped = true; + surface->mapped = true; + + // update older/new active surface + output->previous_active = output->active; + output->active = surface; + + // add to the layer and inflict damage + weston_view_set_output(ev, output->output); + weston_layer_entry_insert(&ivi->normal.view_list, &ev->layer_link); + weston_view_geometry_dirty(ev); + weston_surface_damage(ev->surface); + + // handle input / keyboard + if (ivi_seat) + ivi_shell_activate_surface(surface, ivi_seat, WESTON_ACTIVATE_FLAG_NONE); + } + + weston_view_set_position(surface->view, x, y); + weston_desktop_surface_set_size(surface->dsurface, width, height); + weston_desktop_surface_set_orientation(surface->dsurface, orientation); + surface->orientation = orientation; + + weston_compositor_schedule_repaint(ivi->compositor); + + weston_log("%s() Setting to x=%d, y=%d, width=%d, height=%d, orientation=%d\n", + __func__, x, y, width, height, orientation); + +} + +static int +shell_ivi_surf_count_split_surfaces(struct ivi_compositor *ivi) +{ + int count = 0; + struct ivi_surface *surf; + + wl_list_for_each(surf, &ivi->surfaces, link) { + if (surf->orientation > AGL_SHELL_TILE_ORIENTATION_NONE) + count++; + } + + return count; +} + + +static +void shell_set_app_split(struct wl_client *client, struct wl_resource *res, + const char *app_id, uint32_t orientation, int32_t width, + struct wl_resource *output_res) +{ + struct ivi_surface *surf; + struct ivi_compositor *ivi = wl_resource_get_user_data(res); + + struct weston_head *head = weston_head_from_resource(output_res); + struct weston_output *woutput = weston_head_get_output(head); + struct ivi_output *output = to_ivi_output(woutput); + + if (!app_id) + return; + + if (shell_ivi_surf_count_split_surfaces(ivi) > 2) { + weston_log("Found more than two split surfaces in tile orientation.\n"); + return; + } + + /* add it as pending until */ + surf = ivi_find_app(ivi, app_id); + if (!surf) { + _ivi_set_pending_desktop_surface_split(output_res, app_id, orientation); + return; + } + + if (output->previous_active) { + struct weston_view *ev = output->previous_active->view; + + if (!weston_view_is_mapped(ev)) + weston_view_update_transform(ev); + else + weston_layer_entry_remove(&ev->layer_link); + + ev->is_mapped = true; + ev->surface->is_mapped = true; + output->previous_active->mapped = true; + + weston_view_set_output(ev, woutput); + + weston_layer_entry_insert(&ivi->normal.view_list, &ev->layer_link); + + _ivi_set_shell_surface_split(output->previous_active, NULL, + reverse_orientation(orientation), false); + + if (orientation == AGL_SHELL_TILE_ORIENTATION_NONE && + output->active == surf) { + output->active = output->previous_active; + } + } + + _ivi_set_shell_surface_split(surf, NULL, orientation, false); +} + 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); } @@ -1508,8 +1964,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 = { @@ -1518,7 +1983,15 @@ static const struct agl_shell_interface agl_shell_implementation = { .set_panel = shell_set_panel, .activate_app = shell_activate_app, .destroy = shell_destroy, - .set_activate_region = shell_set_activate_region + .set_activate_region = shell_set_activate_region, + .deactivate_app = shell_new_deactivate_app, + .set_app_float = shell_set_app_float, + .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, + .set_app_split = shell_set_app_split, }; static const struct agl_shell_ext_interface agl_shell_ext_implementation = { @@ -1622,18 +2095,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); } @@ -1652,6 +2127,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; } @@ -1661,6 +2137,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 @@ -1687,54 +2165,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; } } @@ -1818,7 +2297,7 @@ int ivi_shell_create_global(struct ivi_compositor *ivi) { ivi->agl_shell = wl_global_create(ivi->compositor->wl_display, - &agl_shell_interface, 4, + &agl_shell_interface, 11, ivi, bind_agl_shell); if (!ivi->agl_shell) { weston_log("Failed to create wayland global.\n");