X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fcompositor.c;h=60d5dd298f3bc0ba0ac9363dcd5890af976b01e7;hb=359a0612e48d7d21d5247199ca57063bd5965f71;hp=564153bc6270050bcbb8f5c60668d8f15c7e52dc;hpb=897449688a9c7f934d45acd1eaa09d766d6da67a;p=src%2Fagl-compositor.git diff --git a/src/compositor.c b/src/compositor.c index 564153b..60d5dd2 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -79,6 +79,95 @@ sigint_helper(int sig) raise(SIGUSR2); } +void +ivi_layout_save(struct ivi_compositor *ivi, struct ivi_output *output) +{ + struct ivi_output *new_output; + ivi->need_ivi_output_relayout = true; + + new_output = zalloc(sizeof(*new_output)); + + new_output->ivi = ivi; + new_output->background = output->background; + + new_output->top = output->top; + new_output->bottom = output->bottom; + new_output->left = output->left; + new_output->right = output->right; + + new_output->active = output->active; + new_output->previous_active = output->previous_active; + new_output->name = strdup(output->name); + if (output->app_ids) + new_output->app_ids = strdup(output->app_ids); + + new_output->area = output->area; + new_output->area_saved = output->area_saved; + new_output->area_activation = output->area_activation; + + weston_log("saving output layout for output %s\n", new_output->name); + + wl_list_insert(&ivi->saved_outputs, &new_output->link); +} + +void +ivi_layout_restore(struct ivi_compositor *ivi, struct ivi_output *n_output) +{ + struct ivi_output *output = NULL; + struct ivi_output *iter_output; + + if (!ivi->need_ivi_output_relayout) + return; + + ivi->need_ivi_output_relayout = false; + + wl_list_for_each(iter_output, &ivi->saved_outputs, link) { + if (strcmp(n_output->name, iter_output->name) == 0) { + output = iter_output; + break; + } + } + + if (!output) + return; + + weston_log("restoring output layout for output %s\n", output->name); + n_output->background = output->background; + + n_output->top = output->top; + n_output->bottom = output->bottom; + n_output->left = output->left; + n_output->right = output->right; + + n_output->active = output->active; + n_output->previous_active = output->previous_active; + if (output->app_ids) + n_output->app_ids = strdup(output->app_ids); + + n_output->area = output->area; + n_output->area_saved = output->area_saved; + n_output->area_activation = output->area_activation; + + free(output->app_ids); + free(output->name); + wl_list_remove(&output->link); + free(output); +} + +void +ivi_layout_destroy_saved_outputs(struct ivi_compositor *ivi) +{ + struct ivi_output *output, *output_next; + + wl_list_for_each_safe(output, output_next, &ivi->saved_outputs, link) { + free(output->app_ids); + free(output->name); + + wl_list_remove(&output->link); + free(output); + } +} + static void handle_output_destroy(struct wl_listener *listener, void *data) { @@ -87,11 +176,14 @@ handle_output_destroy(struct wl_listener *listener, void *data) output = wl_container_of(listener, output, output_destroy); assert(output->output == data); - if (output->fullscreen_view.fs->view) { + if (output->fullscreen_view.fs && + output->fullscreen_view.fs->view) { weston_surface_destroy(output->fullscreen_view.fs->view->surface); output->fullscreen_view.fs->view = NULL; } + ivi_layout_save(output->ivi, output); + output->output = NULL; wl_list_remove(&output->output_destroy.link); } @@ -112,19 +204,19 @@ static void ivi_output_configure_app_id(struct ivi_output *ivi_output) { if (ivi_output->config) { - if (ivi_output->app_id != NULL) + if (ivi_output->app_ids != NULL) return; weston_config_section_get_string(ivi_output->config, "agl-shell-app-id", - &ivi_output->app_id, + &ivi_output->app_ids, NULL); - if (ivi_output->app_id == NULL) + if (ivi_output->app_ids == NULL) return; weston_log("Will place app_id %s on output %s\n", - ivi_output->app_id, ivi_output->name); + ivi_output->app_ids, ivi_output->name); } } @@ -327,6 +419,23 @@ parse_transform(const char *transform, uint32_t *out) return -1; } +static int +parse_activation_area(const char *geometry, struct ivi_output *output) +{ + int n; + unsigned width, height, x, y; + + n = sscanf(geometry, "%ux%u+%u,%u", &width, &height, &x, &y); + if (n != 4) { + return -1; + } + output->area_activation.width = width; + output->area_activation.height = height; + output->area_activation.x = x; + output->area_activation.y = y; + return 0; +} + static int configure_output(struct ivi_output *output) { @@ -350,6 +459,10 @@ configure_output(struct ivi_output *output) if (parse_transform(t, &transform) < 0) weston_log("Invalid transform \"%s\" for output %s\n", t, output->name); + weston_config_section_get_string(section, "activation-area", &t, ""); + if (parse_activation_area(t, output) < 0) + weston_log("Invalid activation-area \"%s\" for output %s\n", + t, output->name); free(t); } @@ -432,6 +545,8 @@ try_attach_enable_heads(struct ivi_output *output) for (size_t i = fail_len; i < output->add_len; ++i) add_head_destroyed_listener(output->add[i]); + ivi_layout_restore(output->ivi, output); + output->add_len = fail_len; return 0; } @@ -466,8 +581,22 @@ head_disable(struct ivi_compositor *ivi, struct weston_head *head) weston_head_detach(head); if (count_heads(ivi_output->output) == 0) { - weston_output_disable(ivi_output->output); + if (ivi_output->output) { + /* ivi_output->output destruction may be deferred in + * some cases (see drm_output_destroy()), so we need to + * forcibly trigger the destruction callback now, or + * otherwise would later access data that we are about + * to free + */ + struct weston_output *save = ivi_output->output; + + handle_output_destroy(&ivi_output->output_destroy, save); + weston_output_destroy(save); + } } + wl_list_remove(&ivi_output->link); + free(ivi_output->app_ids); + free(ivi_output); } static struct weston_config_section * @@ -1245,11 +1374,12 @@ choose_default_backend(void) } static int -compositor_init_config(struct weston_compositor *compositor, - struct weston_config *config) +compositor_init_config(struct ivi_compositor *ivi) { struct xkb_rule_names xkb_names; struct weston_config_section *section; + struct weston_compositor *compositor = ivi->compositor; + struct weston_config *config = ivi->config; int repaint_msec; bool vt_switching; bool require_input; @@ -1282,6 +1412,11 @@ compositor_init_config(struct weston_compositor *compositor, /* agl-compositor.ini [core] */ section = weston_config_get_section(config, "core", NULL, NULL); + weston_config_section_get_bool(section, "disable-cursor", + &ivi->disable_cursor, false); + weston_config_section_get_bool(section, "activate-by-default", + &ivi->activate_by_default, true); + weston_config_section_get_bool(section, "require-input", &require_input, true); compositor->require_input = require_input; @@ -1646,6 +1781,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da }; wl_list_init(&ivi.outputs); + wl_list_init(&ivi.saved_outputs); wl_list_init(&ivi.surfaces); wl_list_init(&ivi.pending_surfaces); wl_list_init(&ivi.popup_pending_apps); @@ -1698,11 +1834,6 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da if (!backend) backend = choose_default_backend(); } - /* from [core] */ - weston_config_section_get_bool(section, "hide-cursor", - &ivi.hide_cursor, false); - weston_config_section_get_bool(section, "activate-by-default", - &ivi.activate_by_default, true); display = wl_display_create(); loop = wl_display_get_event_loop(display); @@ -1744,7 +1875,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da goto error_signals; } - if (compositor_init_config(ivi.compositor, ivi.config) < 0) + if (compositor_init_config(&ivi) < 0) goto error_compositor; if (load_backend(&ivi, backend, &argc, argv) < 0) { @@ -1795,7 +1926,12 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da weston_compositor_wake(ivi.compositor); ivi_shell_create_global(&ivi); - ivi_launch_shell_client(&ivi); + + ivi_launch_shell_client(&ivi, "shell-client", + &ivi.shell_client.client); + ivi_launch_shell_client(&ivi, "shell-client-ext", + &ivi.shell_client_ext.client); + if (debug) ivi_screenshooter_create(&ivi); ivi_agl_systemd_notify(&ivi);