summaryrefslogtreecommitdiff
path: root/src/core/meta-context-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/meta-context-main.c')
-rw-r--r--src/core/meta-context-main.c702
1 files changed, 0 insertions, 702 deletions
diff --git a/src/core/meta-context-main.c b/src/core/meta-context-main.c
deleted file mode 100644
index 8f669151a..000000000
--- a/src/core/meta-context-main.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2006 Elijah Newren
- * Copyright (C) 2021 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include "core/meta-context-main.h"
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND)
-#include <systemd/sd-login.h>
-#endif /* HAVE_WAYLAND && HAVE_NATIVE_BACKEND */
-
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/meta-virtual-monitor.h"
-#include "backends/x11/cm/meta-backend-x11-cm.h"
-#include "meta/meta-backend.h"
-#include "wayland/meta-wayland.h"
-#include "x11/session.h"
-
-#ifdef HAVE_NATIVE_BACKEND
-#include "backends/native/meta-backend-native.h"
-#endif
-
-#ifdef HAVE_WAYLAND
-#include "backends/x11/nested/meta-backend-x11-nested.h"
-#endif
-
-typedef struct _MetaContextMainOptions
-{
- struct {
- char *display_name;
- gboolean replace;
- gboolean sync;
- gboolean force;
- } x11;
- struct {
- char *save_file;
- char *client_id;
- gboolean disable;
- } sm;
-#ifdef HAVE_WAYLAND
- gboolean wayland;
- gboolean nested;
- gboolean no_x11;
- char *wayland_display;
-#endif
-#ifdef HAVE_NATIVE_BACKEND
- gboolean display_server;
- gboolean headless;
-#endif
-#ifdef HAVE_NATIVE_BACKEND
- GList *virtual_monitor_infos;
-#endif
-} MetaContextMainOptions;
-
-struct _MetaContextMain
-{
- GObject parent;
-
- MetaContextMainOptions options;
-
- MetaCompositorType compositor_type;
-
- GList *persistent_virtual_monitors;
-};
-
-G_DEFINE_TYPE (MetaContextMain, meta_context_main, META_TYPE_CONTEXT)
-
-static gboolean
-check_configuration (MetaContextMain *context_main,
- GError **error)
-{
-#ifdef HAVE_WAYLAND
- if (context_main->options.x11.force && context_main->options.no_x11)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode with no X11");
- return FALSE;
- }
- if (context_main->options.x11.force && context_main->options.wayland)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode with Wayland enabled");
- return FALSE;
- }
- if (context_main->options.x11.force && context_main->options.nested)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode nested");
- return FALSE;
- }
-#endif /* HAVE_WAYLAND */
-
-#ifdef HAVE_NATIVE_BACKEND
- if (context_main->options.x11.force && context_main->options.display_server)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode as a display server");
- return FALSE;
- }
-
- if (context_main->options.x11.force && context_main->options.headless)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode headlessly");
- return FALSE;
- }
-
- if (context_main->options.display_server && context_main->options.headless)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in display server mode headlessly");
- return FALSE;
- }
-#endif /* HAVE_NATIVE_BACKEND */
-
- if (context_main->options.sm.save_file &&
- context_main->options.sm.client_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't specify both SM save file and SM client id");
- return FALSE;
- }
-
- return TRUE;
-}
-
-#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
-static gboolean
-session_type_is_supported (const char *session_type)
-{
- return (g_strcmp0 (session_type, "x11") == 0) ||
- (g_strcmp0 (session_type, "wayland") == 0);
-}
-
-static char *
-find_session_type (GError **error)
-{
- char **sessions = NULL;
- char *session_id;
- char *session_type;
- const char *session_type_env;
- gboolean is_tty = FALSE;
- int ret, i;
-
- ret = sd_pid_get_session (0, &session_id);
- if (ret == 0 && session_id != NULL)
- {
- ret = sd_session_get_type (session_id, &session_type);
- free (session_id);
-
- if (ret == 0)
- {
- if (session_type_is_supported (session_type))
- goto out;
- else
- is_tty = g_strcmp0 (session_type, "tty") == 0;
- free (session_type);
- }
- }
- else if (sd_uid_get_sessions (getuid (), 1, &sessions) > 0)
- {
- for (i = 0; sessions[i] != NULL; i++)
- {
- ret = sd_session_get_type (sessions[i], &session_type);
-
- if (ret < 0)
- continue;
-
- if (session_type_is_supported (session_type))
- {
- g_strfreev (sessions);
- goto out;
- }
-
- free (session_type);
- }
- }
- g_strfreev (sessions);
-
- session_type_env = g_getenv ("XDG_SESSION_TYPE");
- if (session_type_is_supported (session_type_env))
- {
- /* The string should be freeable */
- session_type = strdup (session_type_env);
- goto out;
- }
-
- /* Legacy support for starting through xinit */
- if (is_tty && (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY")))
- {
- session_type = strdup ("x11");
- goto out;
- }
-
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Unsupported session type");
- return NULL;
-
-out:
- return session_type;
-}
-#else /* defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) */
-static char *
-find_session_type (GError **error)
-{
- return g_strdup ("x11");
-}
-#endif /* defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) */
-
-static MetaCompositorType
-determine_compositor_type (MetaContextMain *context_main,
- GError **error)
-{
- g_autofree char *session_type = NULL;
-
-#ifdef HAVE_WAYLAND
- if (context_main->options.wayland ||
-#ifdef HAVE_NATIVE_BACKEND
- context_main->options.display_server ||
- context_main->options.headless ||
-#endif /* HAVE_NATIVE_BACKEND */
- context_main->options.nested)
- return META_COMPOSITOR_TYPE_WAYLAND;
-#endif /* HAVE_WAYLAND */
-
- if (context_main->options.x11.force)
- return META_COMPOSITOR_TYPE_X11;
-
- session_type = find_session_type (error);
- if (!session_type)
- return -1;
-
- if (strcmp (session_type, "x11") == 0)
- return META_COMPOSITOR_TYPE_X11;
-#ifdef HAVE_WAYLAND
- else if (strcmp (session_type, "wayland") == 0)
- return META_COMPOSITOR_TYPE_WAYLAND;
-#endif
- else
- g_assert_not_reached ();
-}
-
-static gboolean
-meta_context_main_configure (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
- MetaContextClass *context_class =
- META_CONTEXT_CLASS (meta_context_main_parent_class);
-
- if (!context_class->configure (context, argc, argv, error))
- return FALSE;
-
- if (!check_configuration (context_main, error))
- return FALSE;
-
- context_main->compositor_type = determine_compositor_type (context_main,
- error);
- if (context_main->compositor_type == -1)
- return FALSE;
-
-#ifdef HAVE_WAYLAND
- if (context_main->options.wayland_display)
- meta_wayland_override_display_name (context_main->options.wayland_display);
-#endif
-
- return TRUE;
-}
-
-static MetaCompositorType
-meta_context_main_get_compositor_type (MetaContext *context)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- return context_main->compositor_type;
-}
-
-static MetaX11DisplayPolicy
-meta_context_main_get_x11_display_policy (MetaContext *context)
-{
- MetaCompositorType compositor_type;
-#ifdef HAVE_WAYLAND
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
- char *unit;
-#endif
-
- compositor_type = meta_context_get_compositor_type (context);
- switch (compositor_type)
- {
- case META_COMPOSITOR_TYPE_X11:
- return META_X11_DISPLAY_POLICY_MANDATORY;
- case META_COMPOSITOR_TYPE_WAYLAND:
-#ifdef HAVE_WAYLAND
- if (context_main->options.no_x11)
- return META_X11_DISPLAY_POLICY_DISABLED;
- else if (sd_pid_get_user_unit (0, &unit) < 0)
- return META_X11_DISPLAY_POLICY_MANDATORY;
- else
- return META_X11_DISPLAY_POLICY_ON_DEMAND;
-#else /* HAVE_WAYLAND */
- g_assert_not_reached ();
-#endif /* HAVE_WAYLAND */
- }
-
- g_assert_not_reached ();
-}
-
-static gboolean
-meta_context_main_is_replacing (MetaContext *context)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- return context_main->options.x11.replace;
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static gboolean
-add_persistent_virtual_monitors (MetaContextMain *context_main,
- GError **error)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- GList *l;
-
- for (l = context_main->options.virtual_monitor_infos; l; l = l->next)
- {
- MetaVirtualMonitorInfo *info = l->data;
- MetaVirtualMonitor *virtual_monitor;
-
- virtual_monitor =
- meta_monitor_manager_create_virtual_monitor (monitor_manager,
- info,
- error);
- if (!virtual_monitor)
- {
- g_prefix_error (error, "Failed to add virtual monitor: ");
- return FALSE;
- }
-
- context_main->persistent_virtual_monitors =
- g_list_append (context_main->persistent_virtual_monitors, virtual_monitor);
- }
-
- if (context_main->options.virtual_monitor_infos)
- {
- g_list_free_full (context_main->options.virtual_monitor_infos,
- (GDestroyNotify) meta_virtual_monitor_info_free);
- context_main->options.virtual_monitor_infos = NULL;
-
- meta_monitor_manager_reload (monitor_manager);
- }
-
- return TRUE;
-}
-#endif
-
-static gboolean
-meta_context_main_setup (MetaContext *context,
- GError **error)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- if (!META_CONTEXT_CLASS (meta_context_main_parent_class)->setup (context,
- error))
- return FALSE;
-
- meta_set_syncing (context_main->options.x11.sync || g_getenv ("MUTTER_SYNC"));
-
-#ifdef HAVE_NATIVE_BACKEND
- if (!add_persistent_virtual_monitors (context_main, error))
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-static MetaBackend *
-create_x11_cm_backend (MetaContext *context,
- GError **error)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
-#ifdef HAVE_NATIVE_BACKEND
- if (context_main->options.virtual_monitor_infos)
- g_warning ("Ignoring added virtual monitors in X11 session");
-#endif
-
- return g_initable_new (META_TYPE_BACKEND_X11_CM,
- NULL, error,
- "context", context,
- "display-name", context_main->options.x11.display_name,
- NULL);
-}
-
-#ifdef HAVE_WAYLAND
-static MetaBackend *
-create_nested_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_X11_NESTED,
- NULL, error,
- "context", context,
- NULL);
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static MetaBackend *
-create_headless_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_NATIVE,
- NULL, error,
- "context", context,
- "headless", TRUE,
- NULL);
-}
-
-static MetaBackend *
-create_native_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_NATIVE,
- NULL, error,
- "context", context,
- NULL);
-}
-#endif /* HAVE_NATIVE_BACKEND */
-#endif /* HAVE_WAYLAND */
-
-static MetaBackend *
-meta_context_main_create_backend (MetaContext *context,
- GError **error)
-{
-#ifdef HAVE_WAYLAND
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-#endif
- MetaCompositorType compositor_type;
-
- compositor_type = meta_context_get_compositor_type (context);
- switch (compositor_type)
- {
- case META_COMPOSITOR_TYPE_X11:
- return create_x11_cm_backend (context, error);
- case META_COMPOSITOR_TYPE_WAYLAND:
-#ifdef HAVE_WAYLAND
- if (context_main->options.nested)
- return create_nested_backend (context, error);
-#ifdef HAVE_NATIVE_BACKEND
- else if (context_main->options.headless)
- return create_headless_backend (context, error);
- else
- return create_native_backend (context, error);
-#endif /* HAVE_NATIVE_BACKEND */
-#else /* HAVE_WAYLAND */
- g_assert_not_reached ();
-#endif /* HAVE_WAYLAND */
- }
-
- g_assert_not_reached ();
-}
-
-static void
-meta_context_main_notify_ready (MetaContext *context)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- if (!context_main->options.sm.disable)
- {
- meta_session_init (context,
- context_main->options.sm.client_id,
- context_main->options.sm.save_file);
- }
- g_clear_pointer (&context_main->options.sm.client_id, g_free);
- g_clear_pointer (&context_main->options.sm.save_file, g_free);
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static gboolean
-add_virtual_monitor_cb (const char *option_name,
- const char *value,
- gpointer user_data,
- GError **error)
-{
- MetaContextMain *context_main = user_data;
- int width, height;
- float refresh_rate = 60.0;
-
- if (sscanf (value, "%dx%d@%f",
- &width, &height, &refresh_rate) == 3 ||
- sscanf (value, "%dx%d",
- &width, &height) == 2)
- {
- g_autofree char *serial = NULL;
- MetaVirtualMonitorInfo *virtual_monitor;
- int n_existing_virtual_monitor_infos;
-
- n_existing_virtual_monitor_infos =
- g_list_length (context_main->options.virtual_monitor_infos);
- serial = g_strdup_printf ("0x%.2x", n_existing_virtual_monitor_infos);
- virtual_monitor = meta_virtual_monitor_info_new (width,
- height,
- refresh_rate,
- "MetaVendor",
- "MetaVirtualMonitor",
- serial);
- context_main->options.virtual_monitor_infos =
- g_list_append (context_main->options.virtual_monitor_infos,
- virtual_monitor);
- return TRUE;
- }
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Unrecognizable virtual monitor spec '%s'", value);
- return FALSE;
- }
-}
-#endif /* HAVE_NATIVE_BACKEND */
-
-static void
-meta_context_main_add_option_entries (MetaContextMain *context_main)
-{
- MetaContext *context = META_CONTEXT (context_main);
- GOptionEntry options[] = {
- {
- "replace", 'r', 0, G_OPTION_ARG_NONE,
- &context_main->options.x11.replace,
- N_("Replace the running window manager"),
- NULL
- },
- {
- "display", 'd', 0, G_OPTION_ARG_STRING,
- &context_main->options.x11.display_name,
- N_("X Display to use"),
- "DISPLAY"
- },
- {
- "sm-disable", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.sm.disable,
- N_("Disable connection to session manager"),
- NULL
- },
- {
- "sm-client-id", 0, 0, G_OPTION_ARG_STRING,
- &context_main->options.sm.client_id,
- N_("Specify session management ID"),
- "ID"
- },
- {
- "sm-save-file", 0, 0, G_OPTION_ARG_FILENAME,
- &context_main->options.sm.save_file,
- N_("Initialize session from savefile"),
- "FILE"
- },
- {
- "sync", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.x11.sync,
- N_("Make X calls synchronous"),
- NULL
- },
-#ifdef HAVE_WAYLAND
- {
- "wayland", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.wayland,
- N_("Run as a wayland compositor"),
- NULL
- },
- {
- "nested", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.nested,
- N_("Run as a nested compositor"),
- NULL
- },
- {
- "no-x11", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.no_x11,
- N_("Run wayland compositor without starting Xwayland"),
- NULL
- },
- {
- "wayland-display", 0, 0, G_OPTION_ARG_STRING,
- &context_main->options.wayland_display,
- N_("Specify Wayland display name to use"),
- NULL
- },
-#endif
-#ifdef HAVE_NATIVE_BACKEND
- {
- "display-server", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.display_server,
- N_("Run as a full display server, rather than nested")
- },
- {
- "headless", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.headless,
- N_("Run as a headless display server")
- },
- {
- "virtual-monitor", 0, 0, G_OPTION_ARG_CALLBACK,
- add_virtual_monitor_cb,
- N_("Add persistent virtual monitor (WxH or WxH@R)")
- },
-#endif
- {
- "x11", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.x11.force,
- N_("Run with X11 backend")
- },
- { NULL }
- };
-
- meta_context_add_option_entries (context, options, GETTEXT_PACKAGE);
-}
-
-/**
- * meta_create_context:
- * @name: Human readable name of display server or window manager
- *
- * Create a context.
- *
- * Returns: (transfer full): A new context instance.
- */
-MetaContext *
-meta_create_context (const char *name)
-{
- return g_object_new (META_TYPE_CONTEXT_MAIN,
- "name", name,
- NULL);
-}
-
-static void
-meta_context_main_finalize (GObject *object)
-{
-#ifdef HAVE_NATIVE_BACKEND
- MetaContextMain *context_main = META_CONTEXT_MAIN (object);
-
- g_list_free_full (context_main->persistent_virtual_monitors, g_object_unref);
- context_main->persistent_virtual_monitors = NULL;
-#endif
-
- G_OBJECT_CLASS (meta_context_main_parent_class)->finalize (object);
-}
-
-static void
-meta_context_main_constructed (GObject *object)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (object);
-
- G_OBJECT_CLASS (meta_context_main_parent_class)->constructed (object);
-
- meta_context_main_add_option_entries (context_main);
-}
-
-static void
-meta_context_main_class_init (MetaContextMainClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaContextClass *context_class = META_CONTEXT_CLASS (klass);
-
- object_class->finalize = meta_context_main_finalize;
- object_class->constructed = meta_context_main_constructed;
-
- context_class->configure = meta_context_main_configure;
- context_class->get_compositor_type = meta_context_main_get_compositor_type;
- context_class->get_x11_display_policy =
- meta_context_main_get_x11_display_policy;
- context_class->is_replacing = meta_context_main_is_replacing;
- context_class->setup = meta_context_main_setup;
- context_class->create_backend = meta_context_main_create_backend;
- context_class->notify_ready = meta_context_main_notify_ready;
-}
-
-static void
-meta_context_main_init (MetaContextMain *context_main)
-{
- context_main->compositor_type = -1;
-}