diff options
Diffstat (limited to 'src/core/meta-context-main.c')
-rw-r--r-- | src/core/meta-context-main.c | 702 |
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; -} |