[mutter] Introduce MetaContextMain



commit aa306ac3ca0842ba9183cf0ede8c5ec964204de3
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Mar 3 11:31:24 2021 +0100

    Introduce MetaContextMain
    
    This object intends to replace the scattered functions that are used to
    make up what is effectively a "mutter context". It takes care of the
    command line arguments that is now done in main.c, persistant virtual
    monitors, and the like.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1861>

 src/core/meta-context-main.c    | 663 ++++++++++++++++++++++++++++++++++++++++
 src/core/meta-context-main.h    |  31 ++
 src/core/meta-context-private.h |   1 -
 src/core/meta-context.c         |   2 +-
 src/meson.build                 |   2 +
 src/meta/meta-context.h         |   7 +
 6 files changed, 704 insertions(+), 2 deletions(-)
---
diff --git a/src/core/meta-context-main.c b/src/core/meta-context-main.c
new file mode 100644
index 0000000000..60e507c247
--- /dev/null
+++ b/src/core/meta-context-main.c
@@ -0,0 +1,663 @@
+/*
+ * 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 "core/main-private.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;
+
+#ifdef HAVE_WAYLAND
+  if (context_main->options.no_x11)
+    meta_override_x11_display_policy (META_X11_DISPLAY_POLICY_DISABLED);
+#endif
+
+  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;
+}
+
+#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"));
+  meta_set_replace_current_wm (context_main->options.x11.replace);
+
+#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,
+                         "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,
+                         NULL);
+}
+
+#ifdef HAVE_NATIVE_BACKEND
+static MetaBackend *
+create_headless_backend (MetaContext  *context,
+                         GError      **error)
+{
+  return g_initable_new (META_TYPE_BACKEND_NATIVE,
+                         NULL, error,
+                         "headless", TRUE,
+                         NULL);
+}
+
+static MetaBackend *
+create_native_backend (MetaContext  *context,
+                       GError      **error)
+{
+  return g_initable_new (META_TYPE_BACKEND_NATIVE,
+                         NULL, error,
+                         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_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->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;
+}
diff --git a/src/core/meta-context-main.h b/src/core/meta-context-main.h
new file mode 100644
index 0000000000..9a8ce902bd
--- /dev/null
+++ b/src/core/meta-context-main.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef META_CONTEXT_MAIN_H
+#define META_CONTEXT_MAIN_H
+
+#include "core/meta-context-private.h"
+
+#define META_TYPE_CONTEXT_MAIN (meta_context_main_get_type ())
+G_DECLARE_FINAL_TYPE (MetaContextMain, meta_context_main,
+                      META, CONTEXT_MAIN,
+                      MetaContext)
+
+#endif /* META_CONTEXT_MAIN_H */
diff --git a/src/core/meta-context-private.h b/src/core/meta-context-private.h
index 8a3a6171ed..ca38ddddbb 100644
--- a/src/core/meta-context-private.h
+++ b/src/core/meta-context-private.h
@@ -23,7 +23,6 @@
 
 #include "meta/meta-backend.h"
 #include "meta/meta-context.h"
-#include "meta/meta-enums.h"
 
 struct _MetaContextClass
 {
diff --git a/src/core/meta-context.c b/src/core/meta-context.c
index a7a29d241e..c28c03f3b4 100644
--- a/src/core/meta-context.c
+++ b/src/core/meta-context.c
@@ -86,7 +86,7 @@ meta_context_notify_ready (MetaContext *context)
   META_CONTEXT_GET_CLASS (context)->notify_ready (context);
 }
 
-static MetaCompositorType
+MetaCompositorType
 meta_context_get_compositor_type (MetaContext *context)
 {
   return META_CONTEXT_GET_CLASS (context)->get_compositor_type (context);
diff --git a/src/meson.build b/src/meson.build
index 817cfa2c3d..aba2dc9522 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -371,6 +371,8 @@ mutter_sources = [
   'core/meta-close-dialog.c',
   'core/meta-close-dialog-default.c',
   'core/meta-close-dialog-default-private.h',
+  'core/meta-context-main.c',
+  'core/meta-context-main.h',
   'core/meta-context-private.h',
   'core/meta-context.c',
   'core/meta-fraction.c',
diff --git a/src/meta/meta-context.h b/src/meta/meta-context.h
index 003e863e92..b872e1ca58 100644
--- a/src/meta/meta-context.h
+++ b/src/meta/meta-context.h
@@ -24,11 +24,15 @@
 #include <glib-object.h>
 
 #include "meta/common.h"
+#include "meta/meta-enums.h"
 
 #define META_TYPE_CONTEXT (meta_context_get_type ())
 META_EXPORT
 G_DECLARE_DERIVABLE_TYPE (MetaContext, meta_context, META, CONTEXT, GObject)
 
+META_EXPORT
+MetaContext * meta_create_context (const char *name);
+
 META_EXPORT
 void meta_context_add_option_entries (MetaContext        *context,
                                       const GOptionEntry *entries,
@@ -66,4 +70,7 @@ META_EXPORT
 void meta_context_terminate_with_error (MetaContext *context,
                                         GError      *error);
 
+META_EXPORT
+MetaCompositorType meta_context_get_compositor_type (MetaContext *context);
+
 #endif /* META_CONTEXT_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]