[mutter] context: Add start/run/terminate phases



commit 02176eab83e0ba2f436e64f04786cf56c8090cbc
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue Mar 2 11:53:59 2021 +0100

    context: Add start/run/terminate phases
    
    The start phase creates the MetaDisplay object, and initializes Wayland, and
    creates the main loop.
    
    The run phase runs the main loop and handles returning an error if the
    context was terminated with an error.
    
    The terminate phase terminates the main loop, with or without an error.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1861>

 src/core/meta-context.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/meta/meta-context.h | 15 ++++++++
 2 files changed, 110 insertions(+)
---
diff --git a/src/core/meta-context.c b/src/core/meta-context.c
index a941d50f8a..2b6ff966a2 100644
--- a/src/core/meta-context.c
+++ b/src/core/meta-context.c
@@ -26,8 +26,13 @@
 
 #include "backends/meta-backend-private.h"
 #include "compositor/meta-plugin-manager.h"
+#include "core/display-private.h"
 #include "core/util-private.h"
 
+#ifdef HAVE_WAYLAND
+#include "wayland/meta-wayland.h"
+#endif
+
 enum
 {
   PROP_0,
@@ -43,6 +48,9 @@ typedef struct _MetaContextPrivate
 {
   char *name;
   char *plugin_name;
+
+  GMainLoop *main_loop;
+  GError *termination_error;
 } MetaContextPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (MetaContext, meta_context, G_TYPE_OBJECT)
@@ -132,6 +140,71 @@ meta_context_setup (MetaContext  *context,
   return META_CONTEXT_GET_CLASS (context)->setup (context, error);
 }
 
+gboolean
+meta_context_start (MetaContext  *context,
+                    GError      **error)
+{
+  MetaContextPrivate *priv = meta_context_get_instance_private (context);
+
+#ifdef HAVE_WAYLAND
+  if (meta_context_get_compositor_type (context) ==
+      META_COMPOSITOR_TYPE_WAYLAND)
+    meta_backend_init_wayland (meta_get_backend ());
+#endif
+
+  if (!meta_display_open (error))
+    return FALSE;
+
+  priv->main_loop = g_main_loop_new (NULL, FALSE);
+
+  return TRUE;
+}
+
+gboolean
+meta_context_run_main_loop (MetaContext  *context,
+                            GError      **error)
+{
+  MetaContextPrivate *priv = meta_context_get_instance_private (context);
+
+  if (!priv->main_loop)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Tried to run main loop without having started");
+      return FALSE;
+    }
+
+  g_main_loop_run (priv->main_loop);
+  g_clear_pointer (&priv->main_loop, g_main_loop_unref);
+
+  if (priv->termination_error)
+    {
+      g_propagate_error (error, g_steal_pointer (&priv->termination_error));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+void
+meta_context_terminate (MetaContext *context)
+{
+  MetaContextPrivate *priv = meta_context_get_instance_private (context);
+
+  g_return_if_fail (g_main_loop_is_running (priv->main_loop));
+
+  g_main_loop_quit (priv->main_loop);
+}
+
+void
+meta_context_terminate_with_error (MetaContext *context,
+                                   GError      *error)
+{
+  MetaContextPrivate *priv = meta_context_get_instance_private (context);
+
+  priv->termination_error = g_steal_pointer (&error);
+  meta_context_terminate (context);
+}
+
 static void
 meta_context_get_property (GObject    *object,
                            guint       prop_id,
@@ -177,14 +250,36 @@ meta_context_finalize (GObject *object)
 {
   MetaContext *context = META_CONTEXT (object);
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
+  MetaDisplay *display;
   MetaBackend *backend;
+#ifdef HAVE_WAYLAND
+  MetaWaylandCompositor *compositor;
+  MetaCompositorType compositor_type;
+#endif
 
   backend = meta_get_backend ();
   if (backend)
     meta_backend_prepare_shutdown (backend);
 
+#ifdef HAVE_WAYLAND
+  compositor = meta_wayland_compositor_get_default ();
+  if (compositor)
+    meta_wayland_compositor_prepare_shutdown (compositor);
+#endif
+
+  display = meta_get_display ();
+  if (display)
+    meta_display_close (display, META_CURRENT_TIME);
+
+#ifdef HAVE_WAYLAND
+  compositor_type = meta_context_get_compositor_type (context);
+  if (compositor_type == META_COMPOSITOR_TYPE_WAYLAND)
+    meta_wayland_finalize ();
+#endif
+
   meta_release_backend ();
 
+  g_clear_pointer (&priv->main_loop, g_main_loop_unref);
   g_clear_pointer (&priv->plugin_name, g_free);
   g_clear_pointer (&priv->name, g_free);
 
diff --git a/src/meta/meta-context.h b/src/meta/meta-context.h
index dbe35c825f..1c612c49ac 100644
--- a/src/meta/meta-context.h
+++ b/src/meta/meta-context.h
@@ -43,4 +43,19 @@ META_EXPORT
 gboolean meta_context_setup (MetaContext  *context,
                              GError      **error);
 
+META_EXPORT
+gboolean meta_context_start (MetaContext  *context,
+                             GError      **error);
+
+META_EXPORT
+gboolean meta_context_run_main_loop (MetaContext  *context,
+                                     GError      **error);
+
+META_EXPORT
+void meta_context_terminate (MetaContext *context);
+
+META_EXPORT
+void meta_context_terminate_with_error (MetaContext *context,
+                                        GError      *error);
+
 #endif /* META_CONTEXT_H */


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