summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compositor.c226
-rw-r--r--src/ivi-compositor.h11
2 files changed, 171 insertions, 66 deletions
diff --git a/src/compositor.c b/src/compositor.c
index 2568246..6aec416 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -64,6 +64,9 @@
static int cached_tm_mday = -1;
static struct weston_log_scope *log_scope;
+static void
+weston_output_lazy_align(struct weston_output *output);
+
struct ivi_compositor *
to_ivi_compositor(struct weston_compositor *ec)
{
@@ -101,6 +104,25 @@ ivi_init_parsed_options(struct weston_compositor *compositor)
}
static void
+ivi_backend_destroy(struct ivi_backend *b)
+{
+ wl_list_remove(&b->link);
+ wl_list_remove(&b->heads_changed.link);
+
+ free(b);
+}
+
+
+static void
+ivi_compositor_destroy_backends(struct ivi_compositor *ivi)
+{
+ struct ivi_backend *b, *tmp;
+
+ wl_list_for_each_safe(b, tmp, &ivi->backends, link)
+ ivi_backend_destroy(b);
+}
+
+static void
screenshot_allow_all(struct wl_listener *l, struct weston_output_capture_attempt *att)
{
att->authorized = true;
@@ -226,8 +248,8 @@ ivi_output_configure_app_id(struct ivi_output *ivi_output)
}
static struct ivi_output *
-ivi_ensure_output(struct ivi_compositor *ivi, char *name,
- struct weston_config_section *config,
+ivi_ensure_output(struct ivi_compositor *ivi, struct ivi_backend *ivi_backend,
+ char *name, struct weston_config_section *config,
struct weston_head *head)
{
struct ivi_output *output = NULL;
@@ -264,8 +286,8 @@ ivi_ensure_output(struct ivi_compositor *ivi, char *name,
weston_output_add_destroy_listener(output->output,
&output->output_destroy);
- if (ivi->simple_output_configure) {
- int ret = ivi->simple_output_configure(output->output);
+ if (ivi_backend->simple_output_configure) {
+ int ret = ivi_backend->simple_output_configure(output->output);
if (ret < 0) {
weston_log("Configuring output \"%s\" failed.\n",
weston_head_get_name(head));
@@ -274,6 +296,8 @@ ivi_ensure_output(struct ivi_compositor *ivi, char *name,
return NULL;
}
+ weston_output_lazy_align(output->output);
+
if (weston_output_enable(output->output) < 0) {
weston_log("Enabling output \"%s\" failed.\n",
weston_head_get_name(head));
@@ -618,6 +642,19 @@ process_output(struct ivi_output *output)
return try_attach_enable_heads(output);
}
+static struct weston_head *
+ivi_backend_iterate_heads(struct ivi_compositor *ivi, struct ivi_backend *wb,
+ struct weston_head *iter)
+{
+ while ((iter = weston_compositor_iterate_heads(ivi->compositor, iter))) {
+ if (iter->backend == wb->backend)
+ break;
+ }
+
+ return iter;
+}
+
+
static void
drm_head_disable(struct ivi_compositor *ivi, struct weston_head *head)
{
@@ -689,7 +726,7 @@ find_controlling_output_config(struct weston_config *config,
}
static void
-drm_head_prepare_enable(struct ivi_compositor *ivi, struct weston_head *head)
+drm_head_prepare_enable(struct ivi_compositor *ivi, struct ivi_backend *ivi_backend, struct weston_head *head)
{
const char *name = weston_head_get_name(head);
struct weston_config_section *section;
@@ -717,7 +754,7 @@ drm_head_prepare_enable(struct ivi_compositor *ivi, struct weston_head *head)
if (!output_name)
return;
- output = ivi_ensure_output(ivi, output_name, section, head);
+ output = ivi_ensure_output(ivi, ivi_backend, output_name, section, head);
if (!output)
return;
@@ -734,15 +771,17 @@ drm_heads_changed(struct wl_listener *listener, void *arg)
struct weston_head *head = NULL;
struct ivi_compositor *ivi = to_ivi_compositor(compositor);
struct ivi_output *output;
+ struct ivi_backend *ivi_backend =
+ container_of(listener, struct ivi_backend, heads_changed);
- while ((head = weston_compositor_iterate_heads(ivi->compositor, head))) {
+ while ((head = ivi_backend_iterate_heads(ivi, ivi_backend, head))) {
bool connected = weston_head_is_connected(head);
bool enabled = weston_head_is_enabled(head);
bool changed = weston_head_is_device_changed(head);
bool non_desktop = weston_head_is_non_desktop(head);
if (connected && !enabled && !non_desktop)
- drm_head_prepare_enable(ivi, head);
+ drm_head_prepare_enable(ivi, ivi_backend, head);
else if (!connected && enabled)
drm_head_disable(ivi, head);
else if (enabled && changed)
@@ -765,7 +804,8 @@ drm_heads_changed(struct wl_listener *listener, void *arg)
}
static void
-simple_head_enable(struct ivi_compositor *ivi, struct weston_head *head)
+simple_head_enable(struct ivi_compositor *ivi, struct ivi_backend *ivi_backend,
+ struct weston_head *head)
{
struct ivi_output *output;
struct weston_config_section *section;
@@ -792,7 +832,7 @@ simple_head_enable(struct ivi_compositor *ivi, struct weston_head *head)
if (!output_name)
return;
- output = ivi_ensure_output(ivi, output_name, section, head);
+ output = ivi_ensure_output(ivi, ivi_backend, output_name, section, head);
if (!output) {
weston_log("Failed to create output %s\n", output_name);
return;
@@ -827,15 +867,17 @@ simple_heads_changed(struct wl_listener *listener, void *arg)
bool enabled;
bool changed;
bool non_desktop;
+ struct ivi_backend *ivi_backend =
+ container_of(listener, struct ivi_backend, heads_changed);
- while ((head = weston_compositor_iterate_heads(ivi->compositor, head))) {
+ while ((head = ivi_backend_iterate_heads(ivi, ivi_backend, head))) {
connected = weston_head_is_connected(head);
enabled = weston_head_is_enabled(head);
changed = weston_head_is_device_changed(head);
non_desktop = weston_head_is_non_desktop(head);
if (connected && !enabled && !non_desktop) {
- simple_head_enable(ivi, head);
+ simple_head_enable(ivi, ivi_backend, head);
} else if (!connected && enabled) {
simple_head_disable(head);
} else if (enabled && changed) {
@@ -862,6 +904,7 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
bool force_pixman = false;
bool use_shadow;
bool without_input = false;
+ struct ivi_backend *ivi_backend = NULL;
const struct weston_option options[] = {
{ WESTON_OPTION_STRING, "seat", 0, &config.seat_id },
@@ -891,16 +934,20 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
if (without_input)
ivi->compositor->require_input = !without_input;
- ivi->heads_changed.notify = drm_heads_changed;
- weston_compositor_add_heads_changed_listener(ivi->compositor,
- &ivi->heads_changed);
-
- if (!weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_DRM,
- &config.base)) {
+ ivi_backend = zalloc(sizeof(struct ivi_backend));
+ ivi_backend->backend =
+ weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_DRM,
+ &config.base);
+ if (!ivi_backend->backend) {
weston_log("Failed to load DRM backend\n");
return -1;
}
+ ivi_backend->heads_changed.notify = drm_heads_changed;
+ weston_compositor_add_heads_changed_listener(ivi->compositor,
+ &ivi_backend->heads_changed);
+ wl_list_insert(&ivi->backends, &ivi_backend->link);
+
ivi->drm_api = weston_drm_output_get_api(ivi->compositor);
if (!ivi->drm_api) {
weston_log("Cannot use drm output api.\n");
@@ -943,6 +990,7 @@ windowed_parse_common_options(struct ivi_compositor *ivi, int *argc, char *argv[
static int
windowed_create_outputs(struct ivi_compositor *ivi, int output_count,
+ struct weston_backend *backend,
const char *match_prefix, const char *name_prefix)
{
struct weston_config_section *section = NULL;
@@ -968,7 +1016,7 @@ windowed_create_outputs(struct ivi_compositor *ivi, int output_count,
continue;
}
- if (ivi->window_api->create_head(ivi->backend, output_name) < 0) {
+ if (ivi->window_api->create_head(backend, output_name) < 0) {
free(output_name);
return -1;
}
@@ -981,7 +1029,7 @@ windowed_create_outputs(struct ivi_compositor *ivi, int output_count,
if (asprintf(&default_output, "%s%d", name_prefix, i) < 0)
return -1;
- if (ivi->window_api->create_head(ivi->backend, default_output) < 0) {
+ if (ivi->window_api->create_head(backend, default_output) < 0) {
free(default_output);
return -1;
}
@@ -1027,6 +1075,7 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
int sprawl = 0;
int output_count;
bool force_pixman = false;
+ struct ivi_backend *ivi_backend = NULL;
const struct weston_option options[] = {
{ WESTON_OPTION_STRING, "display", 0, &config.display_name },
@@ -1045,23 +1094,25 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
weston_config_section_get_int(section, "cursor-size",
&config.cursor_size, 32);
- ivi->simple_output_configure = wayland_backend_output_configure;
- ivi->heads_changed.notify = simple_heads_changed;
- weston_compositor_add_heads_changed_listener(ivi->compositor,
- &ivi->heads_changed);
-
- ivi->backend = weston_compositor_load_backend(ivi->compositor,
+ ivi_backend = zalloc(sizeof(struct ivi_backend));
+ ivi_backend->backend = weston_compositor_load_backend(ivi->compositor,
WESTON_BACKEND_WAYLAND,
&config.base);
- if (!ivi->backend) {
- weston_log("Failed to create Wayland backend!\n");
- }
-
free(config.cursor_theme);
free(config.display_name);
- if (!ivi->backend)
+ if (!ivi_backend->backend) {
+ weston_log("Failed to create Wayland backend!\n");
return -1;
+ }
+
+ ivi_backend->simple_output_configure = wayland_backend_output_configure;
+ ivi_backend->heads_changed.notify = simple_heads_changed;
+ weston_compositor_add_heads_changed_listener(ivi->compositor,
+ &ivi_backend->heads_changed);
+
+
+ wl_list_insert(&ivi->backends, &ivi_backend->link);
ivi->window_api = weston_windowed_output_get_api(ivi->compositor);
@@ -1075,7 +1126,7 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
if (ivi->window_api == NULL)
return 0;
- return windowed_create_outputs(ivi, output_count, "WL", "wayland");
+ return windowed_create_outputs(ivi, output_count, ivi_backend->backend, "WL", "wayland");
}
#ifdef HAVE_BACKEND_X11
@@ -1113,6 +1164,7 @@ load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
int no_input = 0;
int output_count;
bool force_pixman = false;
+ struct ivi_backend *ivi_backend = NULL;
const struct weston_option options[] = {
{ WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input },
@@ -1128,27 +1180,31 @@ load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
config.renderer = WESTON_RENDERER_AUTO;
config.no_input = no_input;
- ivi->simple_output_configure = x11_backend_output_configure;
-
- ivi->heads_changed.notify = simple_heads_changed;
- weston_compositor_add_heads_changed_listener(ivi->compositor,
- &ivi->heads_changed);
- ivi->backend = weston_compositor_load_backend(ivi->compositor,
+ ivi_backend = zalloc(sizeof(struct ivi_backend));
+ ivi_backend->backend = weston_compositor_load_backend(ivi->compositor,
WESTON_BACKEND_X11,
&config.base);
- if (!ivi->backend) {
+ if (!ivi_backend->backend) {
weston_log("Failed to create X11 backend!\n");
return -1;
}
+ ivi_backend->simple_output_configure = x11_backend_output_configure;
+ ivi_backend->heads_changed.notify = simple_heads_changed;
+ weston_compositor_add_heads_changed_listener(ivi->compositor,
+ &ivi_backend->heads_changed);
+
+
ivi->window_api = weston_windowed_output_get_api(ivi->compositor);
if (!ivi->window_api) {
weston_log("Cannot use weston_windowed_output_api.\n");
return -1;
}
- return windowed_create_outputs(ivi, output_count, "X", "screen");
+ wl_list_insert(&ivi->backends, &ivi_backend->link);
+
+ return windowed_create_outputs(ivi, output_count, ivi_backend->backend, "X", "screen");
}
#else
static int
@@ -1249,6 +1305,7 @@ load_rdp_backend(struct ivi_compositor *ivi, int *argc, char **argv,
struct weston_rdp_backend_config config = {};
struct weston_config_section *section;
bool no_remotefx_codec = false;
+ struct ivi_backend *ivi_backend = NULL;
struct ivi_output_config *parsed_options = ivi_init_parsed_options(ivi->compositor);
if (!parsed_options)
@@ -1290,23 +1347,28 @@ load_rdp_backend(struct ivi_compositor *ivi, int *argc, char **argv,
parse_options(rdp_options, ARRAY_LENGTH(rdp_options), argc, argv);
weston_log("No clients resize: %d\n", config.no_clients_resize);
- ivi->simple_output_configure = rdp_backend_output_configure;
-
- ivi->heads_changed.notify = simple_heads_changed;
- weston_compositor_add_heads_changed_listener(ivi->compositor,
- &ivi->heads_changed);
- if (!weston_compositor_load_backend(ivi->compositor,
- WESTON_BACKEND_RDP, &config.base)) {
+ ivi_backend = zalloc(sizeof(struct ivi_backend));
+ ivi_backend->backend = weston_compositor_load_backend(ivi->compositor,
+ WESTON_BACKEND_RDP, &config.base);
+ if (!ivi_backend->backend) {
weston_log("Failed to create RDP backend\n");
return -1;
}
+ ivi_backend->simple_output_configure = rdp_backend_output_configure;
+ ivi_backend->heads_changed.notify = simple_heads_changed;
+ weston_compositor_add_heads_changed_listener(ivi->compositor,
+ &ivi_backend->heads_changed);
+
+
free(config.bind_address);
free(config.rdp_key);
free(config.server_cert);
free(config.server_key);
+ wl_list_insert(&ivi->backends, &ivi_backend->link);
+
return 0;
}
#else
@@ -1387,6 +1449,7 @@ load_pipewire_backend(struct ivi_compositor *ivi, int *argc, char **argv,
struct weston_config_section *section;
struct ivi_output_config *parsed_options =
ivi_init_parsed_options(ivi->compositor);
+ struct ivi_backend *ivi_backend = NULL;
if (!parsed_options)
return -1;
@@ -1410,17 +1473,22 @@ load_pipewire_backend(struct ivi_compositor *ivi, int *argc, char **argv,
weston_config_section_get_int(section, "num-outputs",
&config.num_outputs, 1);
- ivi->simple_output_configure = pipewire_backend_output_configure;
- ivi->heads_changed.notify = simple_heads_changed;
- weston_compositor_add_heads_changed_listener(ivi->compositor,
- &ivi->heads_changed);
- if (!weston_compositor_load_backend(ivi->compositor,
- WESTON_BACKEND_PIPEWIRE, &config.base)) {
+ ivi_backend = zalloc(sizeof(struct ivi_backend));
+ ivi_backend->backend = weston_compositor_load_backend(ivi->compositor,
+ WESTON_BACKEND_PIPEWIRE, &config.base);
+ if (!ivi_backend->backend) {
weston_log("Failed to create PipeWire backend\n");
return -1;
}
+ ivi_backend->simple_output_configure = pipewire_backend_output_configure;
+ ivi_backend->heads_changed.notify = simple_heads_changed;
+ weston_compositor_add_heads_changed_listener(ivi->compositor,
+ &ivi_backend->heads_changed);
+
+ wl_list_insert(&ivi->backends, &ivi_backend->link);
+
return 0;
}
#else
@@ -1468,6 +1536,33 @@ load_backend(struct ivi_compositor *ivi, int *argc, char **argv,
}
static int
+load_backends(struct ivi_compositor *ivi, const char *backends,
+ int *argc, char **argv, const char *renderer)
+{
+ const char *p, *end;
+ char buffer[256];
+
+ if (backends == NULL)
+ return 0;
+
+ p = backends;
+ while (*p) {
+ end = strchrnul(p, ',');
+ snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
+
+ if (load_backend(ivi, argc, argv, buffer, renderer) < 0)
+ return -1;
+
+ p = end;
+ while (*p == ',')
+ p++;
+ }
+
+ return 0;
+}
+
+
+static int
load_modules(struct ivi_compositor *ivi, const char *modules,
int *argc, char *argv[], bool *xwayland)
{
@@ -1939,7 +2034,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
struct wl_event_source *signals[3] = { 0 };
struct weston_config_section *section;
/* Command line options */
- char *backend = NULL;
+ char *backends = NULL;
char *socket_name = NULL;
char *log = NULL;
char *modules = NULL;
@@ -1962,7 +2057,8 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
const struct weston_option core_options[] = {
{ WESTON_OPTION_STRING, "renderer", 'r', &renderer },
- { WESTON_OPTION_STRING, "backend", 'B', &backend },
+ { WESTON_OPTION_STRING, "backend", 'B', &backends },
+ { WESTON_OPTION_STRING, "backends", 0, &backends },
{ WESTON_OPTION_STRING, "socket", 'S', &socket_name },
{ WESTON_OPTION_STRING, "log", 0, &log },
{ WESTON_OPTION_BOOLEAN, "help", 'h', &help },
@@ -1985,6 +2081,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
wl_list_init(&ivi.split_pending_apps);
wl_list_init(&ivi.remote_pending_apps);
wl_list_init(&ivi.desktop_clients);
+ wl_list_init(&ivi.backends);
wl_list_init(&ivi.child_process_list);
wl_list_init(&ivi.pending_apps);
@@ -2025,11 +2122,11 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
if (load_config(&ivi.config, no_config, config_file) < 0)
goto error_signals;
section = weston_config_get_section(ivi.config, "core", NULL, NULL);
- if (!backend) {
- weston_config_section_get_string(section, "backend", &backend,
+ if (!backends) {
+ weston_config_section_get_string(section, "backend", &backends,
NULL);
- if (!backend)
- backend = choose_default_backend();
+ if (!backends)
+ backends = choose_default_backend();
}
display = wl_display_create();
@@ -2075,8 +2172,9 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
if (compositor_init_config(&ivi) < 0)
goto error_compositor;
- if (load_backend(&ivi, &argc, argv, backend, renderer) < 0) {
- weston_log("fatal: failed to create compositor backend.\n");
+ ivi.compositor->multi_backend = backends && strchr(backends, ',');
+ if (load_backends(&ivi, backends, &argc, argv, renderer) < 0) {
+ weston_log("fatal: failed to create compositor backend\n");
goto error_compositor;
}
@@ -2163,11 +2261,13 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da
ret = ivi.compositor->exit_code;
+ ivi_compositor_destroy_backends(&ivi);
+
wl_display_destroy_clients(display);
error_compositor:
- free(backend);
- backend = NULL;
+ free(backends);
+ backends = NULL;
free(modules);
modules = NULL;
diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h
index 5c826af..1e8c55a 100644
--- a/src/ivi-compositor.h
+++ b/src/ivi-compositor.h
@@ -59,14 +59,18 @@ struct ivi_output_config {
uint32_t transform;
};
+struct ivi_backend {
+ struct weston_backend *backend;
+ struct wl_listener heads_changed;
+ int (*simple_output_configure)(struct weston_output *output);
+ struct wl_list link;
+};
+
struct ivi_compositor {
struct weston_compositor *compositor;
- struct weston_backend *backend;
struct weston_config *config;
struct ivi_output_config *parsed_options;
- struct wl_listener heads_changed;
- int (*simple_output_configure)(struct weston_output *output);
bool init_failed;
bool disable_cursor;
@@ -117,6 +121,7 @@ struct ivi_compositor {
struct wl_list outputs; /* ivi_output.link */
struct wl_list saved_outputs; /* ivi_output.link */
struct wl_list surfaces; /* ivi_surface.link */
+ struct wl_list backends;
struct weston_desktop *desktop;
struct wl_listener seat_created_listener;