#ifdef HAVE_BACKEND_RDP
#include <libweston/backend-rdp.h>
#endif
-#ifdef HAVE_BACKEND_HEADLESS
-#include <libweston/backend-headless.h>
-#endif
#ifdef HAVE_BACKEND_X11
#include <libweston/backend-x11.h>
#endif
#include "remote.h"
#endif
+#define WINDOWED_DEFAULT_WIDTH 1024
+#define WINDOWED_DEFAULT_HEIGHT 768
+
static int cached_tm_mday = -1;
static struct weston_log_scope *log_scope;
return config;
}
-
-
static void
sigint_helper(int sig)
{
enum weston_compositor_backend backend;
} backend_name_map[] = {
{ "drm", "drm-backend.so", WESTON_BACKEND_DRM },
- { "headless", "headless-backend.so", WESTON_BACKEND_HEADLESS },
- { "pipewire", "pipewire-backend.so", WESTON_BACKEND_PIPEWIRE },
{ "rdp", "rdp-backend.so", WESTON_BACKEND_RDP },
- { "vnc", "vnc-backend.so", WESTON_BACKEND_VNC },
{ "wayland", "wayland-backend.so", WESTON_BACKEND_WAYLAND },
{ "x11", "x11-backend.so", WESTON_BACKEND_X11 },
};
bool
-get_backend_from_string(const char *name,
- enum weston_compositor_backend *backend)
+get_backend_from_string(const char *name, enum weston_compositor_backend *backend)
{
size_t i;
for (i = 0; i < ARRAY_LENGTH(backend_name_map); i++) {
if (strcmp(name, backend_name_map[i].short_name) == 0 ||
- strcmp(name, backend_name_map[i].long_name) == 0) {
+ strcmp(name, backend_name_map[i].long_name) == 0) {
*backend = backend_name_map[i].backend;
return true;
}
return false;
}
-
bool
get_renderer_from_string(const char *name, enum weston_renderer_type *renderer)
{
return false;
}
-
-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)
{
}
static int
-drm_configure_output(struct ivi_output *output)
+ivi_configure_windowed_output_from_config(struct ivi_output *output,
+ struct ivi_output_config *defaults)
{
struct ivi_compositor *ivi = output->ivi;
struct weston_config_section *section = output->config;
- enum weston_drm_backend_output_mode mode =
- WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
- char *modeline = NULL;
- char *gbm_format = NULL;
- char *seat = NULL;
-
- if (section) {
- char *m;
- weston_config_section_get_string(section, "mode", &m, "preferred");
-
- /* This should have been handled earlier */
- assert(strcmp(m, "off") != 0);
-
- if (ivi->cmdline.use_current_mode || strcmp(m, "current") == 0) {
- mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
- } else if (strcmp(m, "preferred") != 0) {
- modeline = m;
- m = NULL;
- }
- free(m);
-
- weston_config_section_get_string(section, "gbm-format",
- &gbm_format, NULL);
-
- weston_config_section_get_string(section, "seat", &seat, "");
- }
-
- if (ivi->drm_api->set_mode(output->output, mode, modeline) < 0) {
- weston_log("Cannot configure output using weston_drm_output_api.\n");
- free(modeline);
- return -1;
- }
- free(modeline);
-
- ivi->drm_api->set_gbm_format(output->output, gbm_format);
- free(gbm_format);
-
- ivi->drm_api->set_seat(output->output, seat);
- free(seat);
-
- return 0;
-}
-
-#define WINDOWED_DEFAULT_WIDTH 1024
-#define WINDOWED_DEFAULT_HEIGHT 768
-
-static int
-windowed_configure_output(struct ivi_output *output)
-{
- struct ivi_compositor *ivi = output->ivi;
- struct weston_config_section *section = output->config;
- int width = WINDOWED_DEFAULT_WIDTH;
- int height = WINDOWED_DEFAULT_HEIGHT;
+ int width;
+ int height;
+ int scale;
if (section) {
char *mode;
if (!mode || sscanf(mode, "%dx%d", &width, &height) != 2) {
weston_log("Invalid mode for output %s. Using defaults.\n",
output->name);
- width = WINDOWED_DEFAULT_WIDTH;
- height = WINDOWED_DEFAULT_HEIGHT;
+ width = defaults->width;
+ height = defaults->height;
}
free(mode);
}
+ scale = defaults->scale;
+
if (ivi->cmdline.width)
width = ivi->cmdline.width;
if (ivi->cmdline.height)
height = ivi->cmdline.height;
+
if (ivi->cmdline.scale)
- weston_output_set_scale(output->output, ivi->cmdline.scale);
+ scale = ivi->cmdline.scale;
+
+ weston_output_set_scale(output->output, scale);
+ weston_output_set_transform(output->output, defaults->transform);
if (ivi->window_api->output_set_size(output->output, width, height) < 0) {
weston_log("Cannot configure output '%s' using weston_windowed_output_api.\n",
return -1;
}
- weston_log("Configured windowed_output_api to %dx%d\n", width, height);
+
+ weston_log("Configured windowed_output_api to %dx%d, scale %d\n",
+ width, height, scale);
return 0;
}
}
static int
-configure_output(struct ivi_output *output)
+drm_configure_output(struct ivi_output *output)
{
struct ivi_compositor *ivi = output->ivi;
struct weston_config_section *section = output->config;
int32_t scale = 1;
uint32_t transform = WL_OUTPUT_TRANSFORM_NORMAL;
-
- /*
- * This can happen with the wayland backend with 'sprawl'. The config
- * is hard-coded, so we don't need to do anything.
- */
- if (!ivi->drm_api && !ivi->window_api)
- return 0;
+ enum weston_drm_backend_output_mode mode =
+ WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
+ char *modeline = NULL;
+ char *gbm_format = NULL;
+ char *seat = NULL;
if (section) {
char *t;
weston_output_set_scale(output->output, scale);
weston_output_set_transform(output->output, transform);
- if (ivi->drm_api)
- return drm_configure_output(output);
- else
- return windowed_configure_output(output);
+ if (section) {
+ char *m;
+ weston_config_section_get_string(section, "mode", &m, "preferred");
+
+ /* This should have been handled earlier */
+ assert(strcmp(m, "off") != 0);
+
+ if (ivi->cmdline.use_current_mode || strcmp(m, "current") == 0) {
+ mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
+ } else if (strcmp(m, "preferred") != 0) {
+ modeline = m;
+ m = NULL;
+ }
+ free(m);
+
+ weston_config_section_get_string(section, "gbm-format",
+ &gbm_format, NULL);
+
+ weston_config_section_get_string(section, "seat", &seat, "");
+ }
+
+ if (ivi->drm_api->set_mode(output->output, mode, modeline) < 0) {
+ weston_log("Cannot configure output using weston_drm_output_api.\n");
+ free(modeline);
+ return -1;
+ }
+ free(modeline);
+
+ ivi->drm_api->set_gbm_format(output->output, gbm_format);
+ free(gbm_format);
+
+ ivi->drm_api->set_seat(output->output, seat);
+ free(seat);
+
+ return 0;
}
/*
fail_len = try_attach_heads(output);
- if (configure_output(output) < 0)
+ if (drm_configure_output(output) < 0)
return -1;
fail_len = try_enable_output(output, fail_len);
}
static void
-head_disable(struct ivi_compositor *ivi, struct weston_head *head)
+drm_head_disable(struct ivi_compositor *ivi, struct weston_head *head)
{
struct weston_output *output;
struct ivi_output *ivi_output;
}
static void
-head_prepare_enable(struct ivi_compositor *ivi, struct weston_head *head)
+drm_head_prepare_enable(struct ivi_compositor *ivi, struct weston_head *head)
{
const char *name = weston_head_get_name(head);
struct weston_config_section *section;
}
static void
-heads_changed(struct wl_listener *listener, void *arg)
+drm_heads_changed(struct wl_listener *listener, void *arg)
{
struct weston_compositor *compositor = arg;
struct weston_head *head = NULL;
bool non_desktop = weston_head_is_non_desktop(head);
if (connected && !enabled && !non_desktop)
- head_prepare_enable(ivi, head);
+ drm_head_prepare_enable(ivi, head);
else if (!connected && enabled)
- head_disable(ivi, head);
+ drm_head_disable(ivi, head);
else if (enabled && changed)
weston_log("Detected a monitor change on head '%s', "
"not bothering to do anything about it.\n",
}
}
+static void
+simple_head_enable(struct ivi_compositor *ivi, struct weston_head *head)
+{
+ struct ivi_output *output;
+ struct weston_config_section *section;
+ char *output_name = NULL;
+ const char *name = weston_head_get_name(head);
+
+ section = find_controlling_output_config(ivi->config, name);
+ if (section) {
+ char *mode;
+
+ weston_config_section_get_string(section, "mode", &mode, NULL);
+ if (mode && strcmp(mode, "off") == 0) {
+ free(mode);
+ return;
+ }
+ free(mode);
+
+ weston_config_section_get_string(section, "name",
+ &output_name, NULL);
+ } else {
+ output_name = strdup(name);
+ }
+
+ if (!output_name)
+ return;
+
+ output = ivi_ensure_output(ivi, output_name, section, head);
+ if (!output) {
+ weston_log("Failed to create output %s\n", output_name);
+ return;
+ }
+
+ add_head_destroyed_listener(head);
+}
+
+
+static void
+simple_head_disable(struct weston_head *head)
+{
+ struct weston_output *output;
+ struct wl_listener *listener;
+
+ listener = weston_head_get_destroy_listener(head, handle_head_destroy);
+ wl_list_empty(&listener->link);
+
+ output = weston_head_get_output(head);
+ assert(output);
+ weston_output_destroy(output);
+}
+
+
+static void
+simple_heads_changed(struct wl_listener *listener, void *arg)
+{
+ struct weston_compositor *compositor = arg;
+ struct ivi_compositor *ivi = to_ivi_compositor(compositor);
+ struct weston_head *head = NULL;
+ bool connected;
+ bool enabled;
+ bool changed;
+ bool non_desktop;
+
+ while ((head = weston_compositor_iterate_heads(ivi->compositor, 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);
+ } else if (!connected && enabled) {
+ simple_head_disable(head);
+ } else if (enabled && changed) {
+ weston_log("Detected a monitor change on head '%s', "
+ "not bothering to do anything about it.\n",
+ weston_head_get_name(head));
+ }
+ weston_head_reset_device_changed(head);
+ }
+}
+
+
#ifdef HAVE_REMOTING
static int
drm_backend_remoted_output_configure(struct weston_output *output,
if (without_input)
ivi->compositor->require_input = !without_input;
- ivi->heads_changed.notify = heads_changed;
+ 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))
+ &config.base)) {
+ weston_log("Failed to load DRM backend\n");
return -1;
+ }
ivi->drm_api = weston_drm_output_get_api(ivi->compositor);
if (!ivi->drm_api) {
return 0;
}
+
+static int
+wayland_backend_output_configure(struct weston_output *output)
+{
+ struct ivi_output_config defaults = {
+ .width = WINDOWED_DEFAULT_WIDTH,
+ .height = WINDOWED_DEFAULT_HEIGHT,
+ .scale = 1,
+ .transform = WL_OUTPUT_TRANSFORM_NORMAL
+ };
+
+ return ivi_configure_windowed_output_from_config(to_ivi_output(output), &defaults);
+}
+
static int
load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
enum weston_renderer_type renderer)
weston_config_section_get_int(section, "cursor-size",
&config.cursor_size, 32);
- ivi->backend = weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_WAYLAND,
+ 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,
+ WESTON_BACKEND_WAYLAND,
&config.base);
+ if (!ivi->backend) {
+ weston_log("Failed to create Wayland backend!\n");
+ }
free(config.cursor_theme);
free(config.display_name);
}
#ifdef HAVE_BACKEND_X11
+static int
+x11_backend_output_configure(struct weston_output *output)
+{
+ struct ivi_output_config defaults = {
+ .width = WINDOWED_DEFAULT_WIDTH,
+ .height = WINDOWED_DEFAULT_HEIGHT,
+ .scale = 1,
+ .transform = WL_OUTPUT_TRANSFORM_NORMAL
+ };
+
+ return ivi_configure_windowed_output_from_config(to_ivi_output(output), &defaults);
+}
+
static int
load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[],
enum weston_renderer_type renderer)
};
int no_input = 0;
int output_count;
- int ret;
bool force_pixman = false;
const struct weston_option options[] = {
config.renderer = WESTON_RENDERER_AUTO;
config.no_input = no_input;
- if (!weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_X11, &config.base))
+ 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,
+ WESTON_BACKEND_X11,
+ &config.base);
+ if (!ivi->backend) {
+ weston_log("Failed to create X11 backend!\n");
return -1;
+ }
ivi->window_api = weston_windowed_output_get_api(ivi->compositor);
if (!ivi->window_api) {
}
#endif
-#ifdef HAVE_BACKEND_HEADLESS
-static int
-load_headless_backend(struct ivi_compositor *ivi, int *argc, char **argv,
- enum weston_renderer_type renderer)
-{
- struct weston_headless_backend_config config = {};
-
- bool force_pixman = false;
- bool fullscreen;
- bool force_gl = false;
- int output_count;
-
- struct weston_compositor *c = ivi->compositor;
- struct weston_backend *wb = NULL;
-
- const struct weston_option options[] = {
- { WESTON_OPTION_BOOLEAN, "use-pixman", false, &force_pixman },
- { WESTON_OPTION_BOOLEAN, "use-gl", false, &force_gl },
- };
-
- windowed_parse_common_options(ivi, argc, argv, &force_pixman,
- &fullscreen, &output_count);
-
- parse_options(options, ARRAY_LENGTH(options), argc, argv);
-
- if ((force_pixman && force_gl) ||
- (renderer != WESTON_RENDERER_AUTO && (force_pixman || force_gl))) {
- weston_log("Conflicting renderer specifications\n");
- return -1;
- } else if (force_pixman) {
- config.renderer = WESTON_RENDERER_PIXMAN;
- } else if (force_gl) {
- config.renderer = WESTON_RENDERER_GL;
- } else {
- config.renderer = renderer;
- }
-
- config.base.struct_version = WESTON_HEADLESS_BACKEND_CONFIG_VERSION;
- config.base.struct_size = sizeof(struct weston_headless_backend_config);
-
- /* load the actual headless-backend and configure it */
- if (!weston_compositor_load_backend(c, WESTON_BACKEND_HEADLESS, &config.base))
- return -1;
-
- ivi->window_api = weston_windowed_output_get_api(c);
- if (!ivi->window_api) {
- weston_log("Cannot use weston_windowed_output_api.\n");
- return -1;
- }
-
- wb = weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_HEADLESS, &config.base);
- if (!wb)
- return -1;
-
- if (ivi->window_api->create_head(wb, "headless") < 0) {
- weston_log("Cannot create headless back-end\n");
- return -1;
- }
-
- return 0;
-}
-#else
-static int
-load_headless_backend(struct ivi_compositor *ivi, int *argc, char **argv, enum weston_renderer_type renderer)
-{
- return -1;
-}
-#endif
-
#ifdef HAVE_BACKEND_RDP
static void
weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
parse_options(rdp_options, ARRAY_LENGTH(rdp_options), argc, argv);
ivi->simple_output_configure = rdp_backend_output_configure;
- if (!weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_RDP, &config.base))
+
+ 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)) {
+ weston_log("Failed to create RDP backend\n");
return -1;
+ }
free(config.bind_address);
free(config.rdp_key);
switch (backend) {
case WESTON_BACKEND_DRM:
return load_drm_backend(ivi, argc, argv, renderer);
- case WESTON_BACKEND_HEADLESS:
- return load_headless_backend(ivi, argc, argv, renderer);
case WESTON_BACKEND_RDP:
return load_rdp_backend(ivi, argc, argv);
case WESTON_BACKEND_WAYLAND: