diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 21fbef762..85eb783ab 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -2452,7 +2452,7 @@ update_outputs(struct drm_backend *b, struct udev_device *drm_device) /* FIXME: handle zero outputs, without terminating */ if (b->connector_allocator == 0) - wl_display_terminate(b->compositor->wl_display); + weston_compositor_exit(b->compositor); } static int @@ -2873,12 +2873,6 @@ drm_backend_create(struct weston_compositor *compositor, b->use_pixman = param->use_pixman; - if (weston_compositor_init(compositor, argc, argv, - config) < 0) { - weston_log("%s failed\n", __func__); - goto err_base; - } - /* Check if we run drm-backend using weston-launch */ compositor->launcher = weston_launcher_connect(compositor, param->tty, param->seat_id, true); diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c index 6a640eeb9..7117bc5fd 100644 --- a/src/compositor-fbdev.c +++ b/src/compositor-fbdev.c @@ -826,10 +826,6 @@ fbdev_backend_create(struct weston_compositor *compositor, int *argc, char *argv return NULL; backend->compositor = compositor; - if (weston_compositor_init(compositor, argc, argv, - config) < 0) - goto out_free; - if (weston_compositor_set_presentation_clock_software( compositor) < 0) goto out_compositor; @@ -902,8 +898,6 @@ out_udev: out_compositor: weston_compositor_shutdown(compositor); - -out_free: free(backend); return NULL; diff --git a/src/compositor-headless.c b/src/compositor-headless.c index d706fcd9d..dba21a60d 100644 --- a/src/compositor-headless.c +++ b/src/compositor-headless.c @@ -218,8 +218,7 @@ headless_destroy(struct weston_compositor *ec) static struct headless_backend * headless_backend_create(struct weston_compositor *compositor, struct headless_parameters *param, - const char *display_name, int *argc, char *argv[], - struct weston_config *config) + const char *display_name) { struct headless_backend *b; @@ -228,9 +227,6 @@ headless_backend_create(struct weston_compositor *compositor, return NULL; b->compositor = compositor; - if (weston_compositor_init(compositor, argc, argv, config) < 0) - goto err_free; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) goto err_free; @@ -288,8 +284,7 @@ backend_init(struct weston_compositor *compositor, if (weston_parse_transform(transform, ¶m.transform) < 0) weston_log("Invalid transform \"%s\"\n", transform); - b = headless_backend_create(compositor, ¶m, display_name, - argc, argv, config); + b = headless_backend_create(compositor, ¶m, display_name); if (b == NULL) return -1; return 0; diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c index 96d4b5fd3..86c5b2acd 100644 --- a/src/compositor-rdp.c +++ b/src/compositor-rdp.c @@ -1172,9 +1172,6 @@ rdp_backend_create(struct weston_compositor *compositor, return NULL; b->compositor = compositor; - if (weston_compositor_init(compositor, argc, argv, wconfig) < 0) - goto err_free; - b->base.destroy = rdp_destroy; b->base.restore = rdp_restore; b->rdp_key = config->rdp_key ? strdup(config->rdp_key) : NULL; @@ -1241,7 +1238,6 @@ err_free_strings: free(b->server_cert); if (b->server_key) free(b->server_key); -err_free: free(b); return NULL; } diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c index deedd18aa..14bd76b5d 100644 --- a/src/compositor-rpi.c +++ b/src/compositor-rpi.c @@ -463,9 +463,7 @@ struct rpi_parameters { static struct rpi_backend * rpi_backend_create(struct weston_compositor *compositor, - struct rpi_parameters *param, - int *argc, char *argv[], - struct weston_config *config) + struct rpi_parameters *param) { struct rpi_backend *backend; uint32_t key; @@ -476,10 +474,6 @@ rpi_backend_create(struct weston_compositor *compositor, if (backend == NULL) return NULL; - if (weston_compositor_init(compositor, argc, argv, - config) < 0) - goto out_free; - if (weston_compositor_set_presentation_clock_software( compositor) < 0) goto out_compositor; @@ -550,7 +544,6 @@ out_udev: out_compositor: weston_compositor_shutdown(compositor); -out_free: bcm_host_deinit(); free(backend); @@ -586,7 +579,7 @@ backend_init(struct weston_compositor *compositor, if (weston_parse_transform(transform, ¶m.output_transform) < 0) weston_log("invalid transform \"%s\"\n", transform); - b = rpi_backend_create(compositor, ¶m, argc, argv, config); + b = rpi_backend_create(compositor, ¶m); if (b == NULL) return -1; return 0; diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 626d8debb..35f1de072 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -1404,7 +1404,7 @@ input_handle_button(void *data, struct wl_pointer *pointer, input->keyboard_focus = NULL; if (wl_list_empty(&input->backend->compositor->output_list)) - wl_display_terminate(input->backend->compositor->wl_display); + weston_compositor_exit(input->backend->compositor); return; } @@ -1852,7 +1852,7 @@ wayland_backend_handle_event(int fd, uint32_t mask, void *data) int count = 0; if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { - wl_display_terminate(b->compositor->wl_display); + weston_compositor_exit(b->compositor); return 0; } @@ -1960,10 +1960,6 @@ wayland_backend_create(struct weston_compositor *compositor, int use_pixman, return NULL; b->compositor = compositor; - if (weston_compositor_init(compositor, argc, argv, - config) < 0) - goto err_free; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) goto err_compositor; @@ -2032,7 +2028,6 @@ err_display: wl_display_disconnect(b->parent.wl_display); err_compositor: weston_compositor_shutdown(compositor); -err_free: free(b); return NULL; } diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 8ca809aed..55c85edc3 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -960,7 +960,7 @@ x11_backend_delete_window(struct x11_backend *b, xcb_window_t window) xcb_flush(b->conn); if (wl_list_empty(&b->compositor->output_list)) - wl_display_terminate(b->compositor->wl_display); + weston_compositor_exit(b->compositor); } static void delete_cb(void *data) @@ -1534,9 +1534,6 @@ x11_backend_create(struct weston_compositor *compositor, return NULL; b->compositor = compositor; - if (weston_compositor_init(compositor, argc, argv, config) < 0) - goto err_free; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) goto err_free; diff --git a/src/compositor.c b/src/compositor.c index 06474a26c..dc3f4a5a6 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -4500,16 +4500,27 @@ timeline_key_binding_handler(struct weston_seat *seat, uint32_t time, weston_timeline_open(compositor); } -WL_EXPORT int -weston_compositor_init(struct weston_compositor *ec, - int *argc, char *argv[], - struct weston_config *config) +/** Create the compositor. + * + * This functions creates and initializes a compositor instance. + * + * \param display The Wayland display to be used. + * \param user_data A pointer to an object that can later be retrieved + * using the \ref weston_compositor_get_user_data function. + * \return The compositor instance on success or NULL on failure. + */ +WL_EXPORT struct weston_compositor * +weston_compositor_create(struct wl_display *display, void *user_data) { + struct weston_compositor *ec; struct wl_event_loop *loop; - struct xkb_rule_names xkb_names; - struct weston_config_section *s; - ec->config = config; + ec = zalloc(sizeof *ec); + if (!ec) + return NULL; + + ec->wl_display = display; + ec->user_data = user_data; wl_signal_init(&ec->destroy_signal); wl_signal_init(&ec->create_surface_signal); wl_signal_init(&ec->activate_signal); @@ -4531,19 +4542,19 @@ weston_compositor_init(struct weston_compositor *ec, if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 3, ec, compositor_bind)) - return -1; + goto fail; if (!wl_global_create(ec->wl_display, &wl_subcompositor_interface, 1, ec, bind_subcompositor)) - return -1; + goto fail; if (!wl_global_create(ec->wl_display, &wl_scaler_interface, 2, ec, bind_scaler)) - return -1; + goto fail; if (!wl_global_create(ec->wl_display, &presentation_interface, 1, ec, bind_presentation)) - return -1; + goto fail; wl_list_init(&ec->view_list); wl_list_init(&ec->plane_list); @@ -4560,7 +4571,39 @@ weston_compositor_init(struct weston_compositor *ec, weston_plane_init(&ec->primary_plane, ec, 0, 0); weston_compositor_stack_plane(ec, &ec->primary_plane, NULL); - s = weston_config_get_section(ec->config, "keyboard", NULL, NULL); + wl_data_device_manager_init(ec->wl_display); + + wl_display_init_shm(ec->wl_display); + + loop = wl_display_get_event_loop(ec->wl_display); + ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec); + wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000); + + ec->input_loop = wl_event_loop_create(); + + weston_layer_init(&ec->fade_layer, &ec->layer_list); + weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link); + + weston_compositor_add_debug_binding(ec, KEY_T, + timeline_key_binding_handler, ec); + + weston_compositor_schedule_repaint(ec); + + return ec; + +fail: + free(ec); + return NULL; +} + +static int +weston_compositor_init_config(struct weston_compositor *ec, + struct weston_config *config) +{ + struct xkb_rule_names xkb_names; + struct weston_config_section *s; + + s = weston_config_get_section(config, "keyboard", NULL, NULL); weston_config_section_get_string(s, "keymap_rules", (char **) &xkb_names.rules, NULL); weston_config_section_get_string(s, "keymap_model", @@ -4580,23 +4623,7 @@ weston_compositor_init(struct weston_compositor *ec, weston_config_section_get_int(s, "repeat-delay", &ec->kb_repeat_delay, 400); - wl_data_device_manager_init(ec->wl_display); - - wl_display_init_shm(ec->wl_display); - - loop = wl_display_get_event_loop(ec->wl_display); - ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec); - wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000); - - ec->input_loop = wl_event_loop_create(); - - weston_layer_init(&ec->fade_layer, &ec->layer_list); - weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link); - - weston_compositor_add_debug_binding(ec, KEY_T, - timeline_key_binding_handler, ec); - - s = weston_config_get_section(ec->config, "core", NULL, NULL); + s = weston_config_get_section(config, "core", NULL, NULL); weston_config_section_get_int(s, "repaint-window", &ec->repaint_msec, DEFAULT_REPAINT_WINDOW); if (ec->repaint_msec < -10 || ec->repaint_msec > 1000) { @@ -4607,8 +4634,6 @@ weston_compositor_init(struct weston_compositor *ec, weston_log("Output repaint window is %d ms maximum.\n", ec->repaint_msec); - weston_compositor_schedule_repaint(ec); - return 0; } @@ -4637,8 +4662,6 @@ weston_compositor_shutdown(struct weston_compositor *ec) weston_plane_release(&ec->primary_plane); wl_event_loop_destroy(ec->input_loop); - - weston_config_destroy(ec->config); } WL_EXPORT void @@ -4648,7 +4671,7 @@ weston_compositor_exit_with_code(struct weston_compositor *compositor, if (compositor->exit_code == EXIT_SUCCESS) compositor->exit_code = exit_code; - wl_display_terminate(compositor->wl_display); + weston_compositor_exit(compositor); } WL_EXPORT void @@ -5272,6 +5295,12 @@ load_configuration(struct weston_config **config, int32_t noconfig, return 0; } +static void +handle_exit(struct weston_compositor *c) +{ + wl_display_terminate(c->wl_display); +} + int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; @@ -5296,7 +5325,7 @@ int main(int argc, char *argv[]) int32_t noconfig = 0; int32_t numlock_on; char *config_file = NULL; - struct weston_config *config; + struct weston_config *config = NULL; struct weston_config_section *section; struct wl_client *primary_client; struct wl_listener primary_client_destroyed; @@ -5370,13 +5399,18 @@ int main(int argc, char *argv[]) if (!backend_init) goto out_signals; - ec = zalloc(sizeof *ec); + ec = weston_compositor_create(display, NULL); if (ec == NULL) { weston_log("fatal: failed to create compositor\n"); goto out_signals; } - ec->wl_display = display; + ec->config = config; + if (weston_compositor_init_config(ec, config) < 0) { + ret = EXIT_FAILURE; + goto out_signals; + } + if (backend_init(ec, &argc, argv, config) < 0) { weston_log("fatal: failed to create compositor backend\n"); ret = EXIT_FAILURE; @@ -5393,6 +5427,7 @@ int main(int argc, char *argv[]) ec->idle_time = idle_time; ec->default_pointer_grab = NULL; ec->exit_code = EXIT_SUCCESS; + ec->exit = handle_exit; weston_compositor_log_capabilities(ec); @@ -5463,15 +5498,7 @@ int main(int argc, char *argv[]) ret = ec->exit_code; out: - /* prevent further rendering while shutting down */ - ec->state = WESTON_COMPOSITOR_OFFSCREEN; - - wl_signal_emit(&ec->destroy_signal, ec); - - weston_compositor_xkb_destroy(ec); - - ec->backend->destroy(ec); - free(ec); + weston_compositor_destroy(ec); out_signals: for (i = ARRAY_LENGTH(signals) - 1; i >= 0; i--) @@ -5479,7 +5506,8 @@ out_signals: wl_event_source_remove(signals[i]); wl_display_destroy(display); - + if (config) + weston_config_destroy(config); weston_log_file_close(); free(config_file); @@ -5492,3 +5520,48 @@ out_signals: return ret; } + +/** Destroys the compositor. + * + * This function cleans up the compositor state and destroys it. + * + * \param compositor The compositor to be destroyed. + */ +WL_EXPORT void +weston_compositor_destroy(struct weston_compositor *compositor) +{ + /* prevent further rendering while shutting down */ + compositor->state = WESTON_COMPOSITOR_OFFSCREEN; + + wl_signal_emit(&compositor->destroy_signal, compositor); + + weston_compositor_xkb_destroy(compositor); + + compositor->backend->destroy(compositor); + free(compositor); +} + +/** Instruct the compositor to exit. + * + * This functions does not directly destroy the compositor object, it merely + * command it to start the tear down process. It is not guaranteed that the + * tear down will happen immediately. + * + * \param compositor The compositor to tear down. + */ +WL_EXPORT void +weston_compositor_exit(struct weston_compositor *compositor) +{ + compositor->exit(compositor); +} + +/** Return the user data stored in the compositor. + * + * This function returns the user data pointer set with user_data parameter + * to the \ref weston_compositor_create function. + */ +WL_EXPORT void * +weston_compositor_get_user_data(struct weston_compositor *compositor) +{ + return compositor->user_data; +} diff --git a/src/compositor.h b/src/compositor.h index bec404a7f..faaacc205 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -689,6 +689,9 @@ struct weston_compositor { int32_t repaint_msec; int exit_code; + + void *user_data; + void (*exit)(struct weston_compositor *c); }; struct weston_buffer { @@ -1337,9 +1340,14 @@ weston_buffer_reference(struct weston_buffer_reference *ref, uint32_t weston_compositor_get_time(void); -int -weston_compositor_init(struct weston_compositor *ec, - int *argc, char *argv[], struct weston_config *config); +void +weston_compositor_destroy(struct weston_compositor *ec); +struct weston_compositor * +weston_compositor_create(struct wl_display *display, void *user_data); +void +weston_compositor_exit(struct weston_compositor *ec); +void * +weston_compositor_get_user_data(struct weston_compositor *compositor); int weston_compositor_set_presentation_clock(struct weston_compositor *compositor, clockid_t clk_id);