X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fshell.c;h=f5dc3e3458e022733b20ca61a23b572e221a4948;hb=d8e72099ecbcadc6e8b242686cf012763a5f1a3a;hp=fbd1b726067d4f46707612338ac72841edc09db0;hpb=359a0612e48d7d21d5247199ca57063bd5965f71;p=src%2Fagl-compositor.git diff --git a/src/shell.c b/src/shell.c index fbd1b72..f5dc3e3 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,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); } @@ -706,7 +617,7 @@ 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; } @@ -1168,6 +1079,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) { @@ -1467,13 +1395,28 @@ shell_set_app_float(struct wl_client *client, struct wl_resource *shell_res, 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; - ivi_layout_deactivate(ivi, app_id); + 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 */ @@ -1505,6 +1448,59 @@ shell_set_app_float(struct wl_client *client, struct wl_resource *shell_res, } } +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) @@ -1532,6 +1528,7 @@ shell_set_app_normal(struct wl_client *client, struct wl_resource *shell_res, /* change the role */ surf->role = IVI_SURFACE_ROLE_NONE; + surf->state = NORMAL; surf->desktop.pending_output = ivi_output; wl_list_remove(&surf->link); @@ -1545,6 +1542,9 @@ shell_set_app_normal(struct wl_client *client, struct wl_resource *shell_res, 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); @@ -1613,6 +1613,86 @@ 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 = surf->desktop.last_output; + struct ivi_output *current_completed_output = + surf->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; + } + + 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) { @@ -1639,6 +1719,10 @@ static const struct agl_shell_interface agl_shell_implementation = { .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, }; static const struct agl_shell_ext_interface agl_shell_ext_implementation = { @@ -1742,18 +1826,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); } @@ -1938,7 +2024,7 @@ int ivi_shell_create_global(struct ivi_compositor *ivi) { ivi->agl_shell = wl_global_create(ivi->compositor->wl_display, - &agl_shell_interface, 6, + &agl_shell_interface, 10, ivi, bind_agl_shell); if (!ivi->agl_shell) { weston_log("Failed to create wayland global.\n");