[mutter] Allow mutter to be used as a library



commit bb50f65532f8f513d483436de88b964f6ac0a343
Author: Dan Winship <danw gnome org>
Date:   Sat Mar 5 16:16:26 2011 -0500

    Allow mutter to be used as a library
    
    Move all of the mutter code into a new libmutter-wm.so, split its
    main() method into meta_get_option_context(), meta_init() and
    meta_run(), add methods for using in-process plugins, and add
    libmutter-wm.pc pointing to the new library.
    
    The mutter binary is now just a tiny program that links against
    libmutter-wm. The --version and --mutter-plugins options are handled
    at the mutter level, not in libmutter-wm, and a few strange unused
    command-line options (--no-force-fullscreen and --no-tab-popup) have
    been removed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=643959

 .gitignore                           |    1 +
 configure.in                         |    1 +
 po/POTFILES.in                       |    1 +
 src/Makefile.am                      |   60 +++++---
 src/compositor/meta-plugin-manager.c |   19 ++-
 src/compositor/meta-plugin-manager.h |    2 +
 src/compositor/meta-plugin.c         |   52 ++++--
 src/core/main.c                      |  311 ++++++++++------------------------
 src/core/mutter.c                    |   99 +++++++++++
 src/core/prefs.c                     |    6 -
 src/include/main.h                   |    4 +
 src/include/meta-plugin.h            |    3 +
 src/include/prefs.h                  |    1 -
 src/include/ui.h                     |    2 +-
 src/libmutter-wm.pc.in               |   18 ++
 src/ui/ui.c                          |    4 +-
 16 files changed, 315 insertions(+), 269 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 9ae9649..648049a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,7 @@ POTFILES
 50-metacity-key.xml
 inlinepixbufs.h
 libmutter-private.pc
+libmutter-wm.pc
 mutter
 mutter-theme-viewer
 mutter.desktop
diff --git a/configure.in b/configure.in
index f5018ae..a03cd82 100644
--- a/configure.in
+++ b/configure.in
@@ -511,6 +511,7 @@ doc/man/Makefile
 src/Makefile
 src/wm-tester/Makefile
 src/libmutter-private.pc
+src/libmutter-wm.pc
 src/mutter-plugins.pc
 src/tools/Makefile
 src/compositor/plugins/Makefile
diff --git a/po/POTFILES.in b/po/POTFILES.in
index aceb717..4a683d9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,6 +7,7 @@ src/core/display.c
 src/core/errors.c
 src/core/keybindings.c
 src/core/main.c
+src/core/mutter.c
 src/core/prefs.c
 src/core/screen.c
 src/core/session.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 4740fcc..3aa38ac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,11 +1,28 @@
 # Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
 .AUTOPARALLEL:
 
-lib_LTLIBRARIES = libmutter-private.la
+lib_LTLIBRARIES = libmutter-private.la libmutter-wm.la
 
 SUBDIRS=wm-tester tools compositor/plugins
 
-INCLUDES= MUTTER_CFLAGS@ -I $(srcdir)/include -I$(srcdir)/compositor -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS \" -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" -DMUTTER_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"mutter\" -DSN_API_NOT_YET_FROZEN=1 -DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) -DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) -DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) -DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR \"
+INCLUDES=								\
+	$(MUTTER_CFLAGS)						\
+	-I$(srcdir)/include						\
+	-I$(srcdir)/compositor						\
+	-DMUTTER_LIBEXECDIR=\"$(libexecdir)\"				\
+	-DHOST_ALIAS=\"@HOST_ALIAS \"					\
+	-DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\"		\
+	-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\"				\
+	-DMUTTER_DATADIR=\"$(datadir)\"					\
+	-DG_LOG_DOMAIN=\"mutter\"					\
+	-DSN_API_NOT_YET_FROZEN=1					\
+	-DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION)			\
+	-DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION)			\
+	-DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION)			\
+	-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION)	\
+	-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\"				\
+	-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR \"			\
+	-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
 
 mutter_built_sources = \
 	mutter-marshal.h \
@@ -13,7 +30,7 @@ mutter_built_sources = \
 	mutter-enum-types.h \
 	mutter-enum-types.c
 
-mutter_SOURCES= 				\
+libmutter_wm_la_SOURCES =			\
 	core/async-getprop.c			\
 	core/async-getprop.h			\
 	core/bell.c				\
@@ -134,6 +151,9 @@ mutter_SOURCES= 				\
 	include/all-keybindings.h               \
 	$(mutter_built_sources)
 
+libmutter_wm_la_LDFLAGS = -no-undefined
+libmutter_wm_la_LIBADD  = $(MUTTER_LIBS)
+
 # by setting libmutter_private_la_CFLAGS, the files shared with
 # mutter proper will be compiled with different names.
 libmutter_private_la_CFLAGS =
@@ -152,7 +172,7 @@ libmutter_private_la_SOURCES=			\
 	ui/theme.h
 
 libmutter_private_la_LDFLAGS = -no-undefined
-libmutter_private_la_LIBADD  = @MUTTER_LIBS@
+libmutter_private_la_LIBADD  = $(MUTTER_LIBS)
 
 # Headers installed for plugins; introspected information will
 # be extracted into Mutter-<version>.gir
@@ -196,6 +216,9 @@ mutter_theme_viewer_SOURCES=  \
 
 bin_PROGRAMS=mutter mutter-theme-viewer
 
+mutter_SOURCES = core/mutter.c
+mutter_LDADD = libmutter-wm.la
+
 if HAVE_INTROSPECTION
 include $(INTROSPECTION_MAKEFILE)
 
@@ -212,34 +235,30 @@ typelib_DATA = Meta-$(api_version).typelib
 
 INTROSPECTION_GIRS = Meta-$(api_version).gir
 
-Meta-$(api_version).gir: mutter
+Meta-$(api_version).gir: libmutter-wm.la
 @META_GIR _INCLUDES = GObject-2.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0
 @META_GIR _PACKAGES = clutter-1.0 gtk+-3.0
 @META_GIR _CFLAGS = $(INCLUDES)
- META_GIR@_PROGRAM = $(builddir)/mutter
+ META_GIR@_LIBS = libmutter-wm.la
 @META_GIR _FILES =				\
 	mutter-enum-types.h			\
 	$(libmutterinclude_base_headers)	\
-	$(filter %.c,$(mutter_SOURCES))
+	$(filter %.c,$(libmutter_wm_la_SOURCES))
 @META_GIR _SCANNERFLAGS = --warn-all --warn-error
 
 endif
 
-EFENCE=
-mutter_LDADD= MUTTER_LIBS@ $(EFENCE)
-mutter_LDFLAGS=-export-dynamic
-
-mutter_theme_viewer_LDADD= @MUTTER_LIBS@ libmutter-private.la
+mutter_theme_viewer_LDADD= $(MUTTER_LIBS) libmutter-private.la
 
-testboxes_SOURCES=include/util.h core/util.c include/boxes.h core/boxes.c core/testboxes.c
-testgradient_SOURCES=ui/gradient.h ui/gradient.c ui/testgradient.c
-testasyncgetprop_SOURCES=core/async-getprop.h core/async-getprop.c core/testasyncgetprop.c
+testboxes_SOURCES = core/testboxes.c
+testgradient_SOURCES = ui/testgradient.c
+testasyncgetprop_SOURCES = core/testasyncgetprop.c
 
 noinst_PROGRAMS=testboxes testgradient testasyncgetprop
 
-testboxes_LDADD= @MUTTER_LIBS@
-testgradient_LDADD= @MUTTER_LIBS@
-testasyncgetprop_LDADD= @MUTTER_LIBS@
+testboxes_LDADD = libmutter-wm.la
+testgradient_LDADD = libmutter-wm.la
+testasyncgetprop_LDADD = libmutter-wm.la
 
 @INTLTOOL_DESKTOP_RULE@
 
@@ -253,7 +272,7 @@ wmproperties_in_files=mutter-wm.desktop.in
 wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
 wmproperties_DATA = $(wmproperties_files)
 
-schemadir   = @GCONF_SCHEMA_FILE_DIR@
+schemadir   = $(GCONF_SCHEMA_FILE_DIR)
 schema_in_files = mutter.schemas.in
 schema_DATA = $(schema_in_files:.schemas.in=.schemas)
 
@@ -288,7 +307,7 @@ inlinepixbufs.h: $(IMAGES)
 
 pkgconfigdir = $(libdir)/pkgconfig
 
-pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
+pkgconfig_DATA = libmutter-private.pc libmutter-wm.pc mutter-plugins.pc
 
 EXTRA_DIST=$(desktopfiles_files) 	\
 	$(wmproperties_files)		\
@@ -297,6 +316,7 @@ EXTRA_DIST=$(desktopfiles_files) 	\
 	$(wmproperties_in_files)	\
 	$(schema_in_files)		\
 	libmutter-private.pc.in	\
+	libmutter-wm.pc.in \
 	mutter-plugins.pc.in  \
 	mutter-enum-types.h.in \
 	mutter-enum-types.c.in \
diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c
index 13171ff..1001a01 100644
--- a/src/compositor/meta-plugin-manager.c
+++ b/src/compositor/meta-plugin-manager.c
@@ -63,7 +63,6 @@ meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
   gchar       *path;
   MetaModule  *module;
   GType        plugin_type;
-  MetaPlugin  *plugin;
 
   if (g_path_is_absolute (plugin_name))
     path = g_strdup (plugin_name);
@@ -83,13 +82,25 @@ meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
     }
 
   plugin_type = meta_module_get_plugin_type (module);
+  meta_plugin_manager_register (plugin_mgr, plugin_type);
+
+  g_type_module_unuse (G_TYPE_MODULE (module));
+  g_free (path);
+}
+
+/*
+ * Registers the given plugin type
+ */
+void
+meta_plugin_manager_register (MetaPluginManager *plugin_mgr,
+                              GType              plugin_type)
+{
+  MetaPlugin  *plugin;
+
   plugin_types = g_slist_prepend (plugin_types, GSIZE_TO_POINTER (plugin_type));
 
   plugin = g_object_new (plugin_type, NULL);
   plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
-
-  g_type_module_unuse (G_TYPE_MODULE (module));
-  g_free (path);
 }
 
 void
diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h
index 888f2e8..ec09bdd 100644
--- a/src/compositor/meta-plugin-manager.h
+++ b/src/compositor/meta-plugin-manager.h
@@ -51,6 +51,8 @@ MetaPluginManager * meta_plugin_manager_get_default (void);
 
 void     meta_plugin_manager_load         (MetaPluginManager *mgr,
                                            const gchar       *plugin_name);
+void     meta_plugin_manager_register     (MetaPluginManager *mgr,
+                                           GType              plugin_type);
 void     meta_plugin_manager_initialize   (MetaPluginManager *mgr);
 
 gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c
index a7786ff..b8af442 100644
--- a/src/compositor/meta-plugin.c
+++ b/src/compositor/meta-plugin.c
@@ -22,6 +22,7 @@
  */
 
 #include "meta-plugin.h"
+#include "meta-plugin-manager.h"
 #include "screen.h"
 #include "display.h"
 
@@ -60,18 +61,6 @@ struct _MetaPluginPrivate
 };
 
 static void
-meta_plugin_dispose (GObject *object)
-{
-  G_OBJECT_CLASS (meta_plugin_parent_class)->dispose (object);
-}
-
-static void
-meta_plugin_finalize (GObject *object)
-{
-  G_OBJECT_CLASS (meta_plugin_parent_class)->finalize (object);
-}
-
-static void
 meta_plugin_set_features (MetaPlugin *plugin)
 {
   MetaPluginPrivate  *priv     = plugin->priv;
@@ -103,6 +92,27 @@ meta_plugin_set_features (MetaPlugin *plugin)
 }
 
 static void
+meta_plugin_constructed (GObject *object)
+{
+  meta_plugin_set_features (META_PLUGIN (object));
+
+  if (G_OBJECT_CLASS (meta_plugin_parent_class)->constructed)
+      G_OBJECT_CLASS (meta_plugin_parent_class)->constructed (object);
+}
+
+static void
+meta_plugin_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (meta_plugin_parent_class)->dispose (object);
+}
+
+static void
+meta_plugin_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (meta_plugin_parent_class)->finalize (object);
+}
+
+static void
 meta_plugin_set_property (GObject      *object,
                           guint         prop_id,
                           const GValue *value,
@@ -161,6 +171,7 @@ meta_plugin_class_init (MetaPluginClass *klass)
 {
   GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 
+  gobject_class->constructed     = meta_plugin_constructed;
   gobject_class->finalize        = meta_plugin_finalize;
   gobject_class->dispose         = meta_plugin_dispose;
   gobject_class->set_property    = meta_plugin_set_property;
@@ -207,8 +218,6 @@ meta_plugin_init (MetaPlugin *self)
   MetaPluginPrivate *priv;
 
   self->priv = priv = META_PLUGIN_GET_PRIVATE (self);
-
-  meta_plugin_set_features (self);
 }
 
 gulong
@@ -540,3 +549,18 @@ meta_plugin_get_screen (MetaPlugin *plugin)
   return priv->screen;
 }
 
+/**
+ * meta_plugin_type_register:
+ * @plugin_type: a #MetaPlugin type
+ *
+ * Register @plugin_type as a compositor plugin type to be used.
+ * You must call this before calling meta_init().
+ */
+void
+meta_plugin_type_register (GType plugin_type)
+{
+  MetaPluginManager *plugin_manager;
+
+  plugin_manager = meta_plugin_manager_get_default ();
+  meta_plugin_manager_register (plugin_manager, plugin_type);
+}
diff --git a/src/core/main.c b/src/core/main.c
index 970e831..3fb8c4e 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -75,7 +75,6 @@
 
 #ifdef HAVE_INTROSPECTION
 #include <girepository.h>
-#include "compositor/meta-plugin-manager.h"
 #endif
 
 /**
@@ -113,23 +112,6 @@ log_handler (const gchar   *log_domain,
 }
 
 /**
- * Prints the version notice. This is shown when Mutter is called
- * with the --version switch.
- */
-static void
-version (void)
-{
-  const int latest_year = 2010;
-
-  g_print (_("mutter %s\n"
-             "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
-             "This is free software; see the source for copying conditions.\n"
-             "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
-           VERSION, latest_year);
-  exit (0);
-}
-
-/**
  * Prints a list of which configure script options were used to
  * build this copy of Mutter. This is actually always called
  * on startup, but it's all no-op unless we're in verbose mode
@@ -208,131 +190,72 @@ meta_print_self_identity (void)
 
 /**
  * The set of possible options that can be set on Mutter's
- * command line. This type exists so that meta_parse_options() can
- * write to an instance of it.
+ * command line.
  */
-typedef struct
-{
-  gchar *save_file;
-  gchar *display_name;
-  gchar *client_id;
-  gchar *mutter_plugins;
-  gboolean replace_wm;
-  gboolean disable_sm;
-  gboolean print_version;
-  gboolean sync;
-  gboolean composite;
-  gboolean no_composite;
-  gboolean no_force_fullscreen;
-  gboolean no_tab_popup;
-  gchar *introspect;
-} MetaArguments;
-
-#define COMPOSITE_OPTS_FLAGS 0
+static gchar    *opt_save_file;
+static gchar    *opt_display_name;
+static gchar    *opt_client_id;
+static gboolean  opt_replace_wm;
+static gboolean  opt_disable_sm;
+static gboolean  opt_sync;
+
+static GOptionEntry meta_options[] = {
+  {
+    "sm-disable", 0, 0, G_OPTION_ARG_NONE,
+    &opt_disable_sm,
+    N_("Disable connection to session manager"),
+    NULL
+  },
+  {
+    "replace", 0, 0, G_OPTION_ARG_NONE,
+    &opt_replace_wm,
+    N_("Replace the running window manager"),
+    NULL
+  },
+  {
+    "sm-client-id", 0, 0, G_OPTION_ARG_STRING,
+    &opt_client_id,
+    N_("Specify session management ID"),
+    "ID"
+  },
+  {
+    "display", 'd', 0, G_OPTION_ARG_STRING,
+    &opt_display_name, N_("X Display to use"),
+    "DISPLAY"
+  },
+  {
+    "sm-save-file", 0, 0, G_OPTION_ARG_FILENAME,
+    &opt_save_file,
+    N_("Initialize session from savefile"),
+    "FILE"
+  },
+  {
+    "sync", 0, 0, G_OPTION_ARG_NONE,
+    &opt_sync,
+    N_("Make X calls synchronous"),
+    NULL
+  },
+  {NULL}
+};
 
 /**
- * Parses argc and argv and returns the
- * arguments that Mutter understands in meta_args.
+ * meta_get_option_context: (skip)
  *
- * The strange call signature has to be written like it is so
- * that g_option_context_parse() gets a chance to modify argc and
- * argv.
+ * Returns a #GOptionContext initialized with mutter-related options.
+ * Parse the command-line args with this before calling meta_init().
  *
- * \param argc  Pointer to the number of arguments Mutter was given
- * \param argv  Pointer to the array of arguments Mutter was given
- * \param meta_args  The result of parsing the arguments.
- **/
-static GOptionContext *
-meta_parse_options (int *argc, char ***argv,
-                    MetaArguments *meta_args)
+ * Return value: the #GOptionContext
+ */
+GOptionContext *
+meta_get_option_context (void)
 {
-  MetaArguments my_args = {NULL, NULL, NULL, NULL,
-                           FALSE, FALSE, FALSE, FALSE, FALSE};
-  GOptionEntry options[] = {
-    {
-      "sm-disable", 0, 0, G_OPTION_ARG_NONE,
-      &my_args.disable_sm,
-      N_("Disable connection to session manager"),
-      NULL
-    },
-    {
-      "replace", 0, 0, G_OPTION_ARG_NONE,
-      &my_args.replace_wm,
-      N_("Replace the running window manager with Mutter"),
-      NULL
-    },
-    {
-      "sm-client-id", 0, 0, G_OPTION_ARG_STRING,
-      &my_args.client_id,
-      N_("Specify session management ID"),
-      "ID"
-    },
-    {
-      "display", 'd', 0, G_OPTION_ARG_STRING,
-      &my_args.display_name, N_("X Display to use"),
-      "DISPLAY"
-    },
-    {
-      "sm-save-file", 0, 0, G_OPTION_ARG_FILENAME,
-      &my_args.save_file,
-      N_("Initialize session from savefile"),
-      "FILE"
-    },
-    {
-      "version", 0, 0, G_OPTION_ARG_NONE,
-      &my_args.print_version,
-      N_("Print version"),
-      NULL
-    },
-    {
-      "sync", 0, 0, G_OPTION_ARG_NONE,
-      &my_args.sync,
-      N_("Make X calls synchronous"),
-      NULL
-    },
-    {
-      "no-force-fullscreen", 0, COMPOSITE_OPTS_FLAGS, G_OPTION_ARG_NONE,
-      &my_args.no_force_fullscreen,
-      N_("Don't make fullscreen windows that are maximized and have no decorations"),
-      NULL
-    },
-    {
-      "mutter-plugins", 0, 0, G_OPTION_ARG_STRING,
-      &my_args.mutter_plugins,
-      N_("Comma-separated list of compositor plugins"),
-      "PLUGINS"
-    },
-    {
-      "no-tab-popup", 0, 0, G_OPTION_ARG_NONE,
-      &my_args.no_tab_popup,
-      N_("Whether window popup/frame should be shown when cycling windows."),
-      NULL
-    },
-#ifdef HAVE_INTROSPECTION
-    {
-      "introspect-dump", 0, 0, G_OPTION_ARG_STRING,
-      &my_args.introspect,
-      N_("Internal argument for GObject introspection"), "INTROSPECT"
-    },
-#endif
-    {NULL}
-  };
   GOptionContext *ctx;
-  GError *error = NULL;
 
   ctx = g_option_context_new (NULL);
-  g_option_context_add_main_entries (ctx, options, "mutter");
+  g_option_context_add_main_entries (ctx, meta_options, GETTEXT_PACKAGE);
   g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
   g_option_context_add_group (ctx, cogl_get_option_group ());
 
-  if (!g_option_context_parse (ctx, argc, argv, &error))
-    {
-      g_print ("mutter: %s\n", error->message);
-      exit(1);
-    }
-
-  /* Return the parsed options through the meta_args param. */
-  *meta_args = my_args;
   return ctx;
 }
 
@@ -381,12 +304,12 @@ static GSourceFuncs event_funcs = {
 };
 
 static void
-meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
+meta_clutter_init (void)
 {
   clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
   clutter_x11_disable_event_retrieval ();
   
-  if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv))
+  if (CLUTTER_INIT_SUCCESS == clutter_init (NULL, NULL))
     {
       GSource *source = g_source_new (&event_funcs, sizeof (GSource));
       g_source_attach (source, NULL);
@@ -452,34 +375,18 @@ on_sigterm (void)
 }
 
 /**
- * This is where the story begins. It parses commandline options and
- * environment variables, sets up the screen, hands control off to
- * GTK, and cleans up afterwards.
- *
- * \param argc Number of arguments (as usual)
- * \param argv Array of arguments (as usual)
+ * meta_init: (skip)
  *
- * \bug It's a bit long. It would be good to split it out into separate
- * functions.
+ * Initialize mutter. Call this after meta_get_option_context() and
+ * meta_plugin_type_register(), and before meta_run().
  */
-int
-main (int argc, char **argv)
+void
+meta_init (void)
 {
   struct sigaction act;
   sigset_t empty_mask;
-  MetaArguments meta_args;
-  const gchar *log_domains[] = {
-    NULL, G_LOG_DOMAIN, "Gtk", "Gdk", "GLib",
-    "Pango", "GLib-GObject", "GThread"
-  };
-  guint i;
   GIOChannel *channel;
-  GOptionContext *ctx;
-  MetaPluginManager *mgr;
 
-  if (!g_thread_supported ())
-    g_thread_init (NULL);
-  
   if (setlocale (LC_ALL, "") == NULL)
     meta_warning ("Locale not understood by C library, internationalization will not work\n");
 
@@ -523,8 +430,6 @@ main (int argc, char **argv)
       meta_warning ("Could not change to home directory %s.\n",
                     g_get_home_dir ());
 
-  g_type_init ();
-
   meta_print_self_identity ();
   
   bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR);
@@ -535,79 +440,51 @@ main (int argc, char **argv)
   g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
 #endif
 
-  /* Parse command line arguments.*/
-  ctx = meta_parse_options (&argc, &argv, &meta_args);
+  meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
 
-  if (meta_args.print_version)
-    version ();
-
-  mgr = meta_plugin_manager_get_default ();
-
-  /* This must come before the introspect below, so we load all the plugins
-   * in order to get their get_type functions.
-   */
-  if (meta_args.mutter_plugins)
-    {
-      char **plugins = g_strsplit (meta_args.mutter_plugins, ",", -1);
-      char **plugin;
-
-      for (plugin = plugins; *plugin; plugin++)
-        {
-          g_strstrip (*plugin);
-          meta_plugin_manager_load (mgr, *plugin);
-        }
-      g_strfreev (plugins);
-    }
-
-#ifdef HAVE_INTROSPECTION
-  if (meta_args.introspect)
-    {
-      GError *error = NULL;
-
-      if (!g_irepository_dump (meta_args.introspect, &error))
-        {
-          g_printerr ("failed to dump: %s\n", error->message);
-          return 1;
-        }
-      return 0;
-    }
-#endif
-
-  meta_set_syncing (meta_args.sync || (g_getenv ("MUTTER_SYNC") != NULL));
-
-  meta_select_display (meta_args.display_name);
+  meta_select_display (opt_display_name);
   
-  if (meta_args.replace_wm)
+  if (opt_replace_wm)
     meta_set_replace_current_wm (TRUE);
 
-  if (meta_args.save_file && meta_args.client_id)
+  if (opt_save_file && opt_client_id)
     meta_fatal ("Can't specify both SM save file and SM client id\n");
   
   meta_main_loop = g_main_loop_new (NULL, FALSE);
   
-  meta_ui_init (&argc, &argv);  
+  meta_ui_init ();
 
   /*
    * Clutter can only be initialized after the UI.
    */
-  meta_clutter_init (ctx, &argc, &argv);
+  meta_clutter_init ();
+}
 
-  g_option_context_free (ctx);
+/**
+ * meta_run: (skip)
+ *
+ * Runs mutter. Call this after completing your own initialization.
+ *
+ * Return value: mutter's exit status
+ */
+int
+meta_run (void)
+{
+  const gchar *log_domains[] = {
+    NULL, G_LOG_DOMAIN, "Gtk", "Gdk", "GLib",
+    "Pango", "GLib-GObject", "GThread"
+  };
+  guint i;
 
   /* Load prefs */
   meta_prefs_init ();
   meta_prefs_add_listener (prefs_changed_callback, NULL);
 
-
-#if 1
-
   for (i=0; i<G_N_ELEMENTS(log_domains); i++)
     g_log_set_handler (log_domains[i],
                        G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
                        log_handler, NULL);
 
-#endif
-
   if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
     g_log_set_always_fatal (G_LOG_LEVEL_MASK);
   
@@ -651,38 +528,30 @@ main (int argc, char **argv)
    * or we might try to manage a window before we have the session
    * info
    */
-  if (!meta_args.disable_sm)
+  if (!opt_disable_sm)
     {
-      if (meta_args.client_id == NULL)
+      if (opt_client_id == NULL)
         {
           const gchar *desktop_autostart_id;
   
           desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
  
           if (desktop_autostart_id != NULL)
-            meta_args.client_id = g_strdup (desktop_autostart_id);
+            opt_client_id = g_strdup (desktop_autostart_id);
         }
 
       /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
        * use the same client id. */
       g_unsetenv ("DESKTOP_AUTOSTART_ID");
 
-      meta_session_init (meta_args.client_id, meta_args.save_file);
+      meta_session_init (opt_client_id, opt_save_file);
     }
   /* Free memory possibly allocated by the argument parsing which are
    * no longer needed.
    */
-  g_free (meta_args.save_file);
-  g_free (meta_args.display_name);
-  g_free (meta_args.client_id);
-
-  if (meta_args.no_force_fullscreen)
-    meta_prefs_set_force_fullscreen (FALSE);
-
-  if (meta_args.no_tab_popup)
-    {
-      meta_prefs_override_no_tab_popup (TRUE);
-    }
+  g_free (opt_save_file);
+  g_free (opt_display_name);
+  g_free (opt_client_id);
 
   if (!meta_display_open ())
     meta_exit (META_EXIT_ERROR);
diff --git a/src/core/mutter.c b/src/core/mutter.c
new file mode 100644
index 0000000..64085c2
--- /dev/null
+++ b/src/core/mutter.c
@@ -0,0 +1,99 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright 2011 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 <stdlib.h>
+
+#include "main.h"
+#include "util.h"
+#ifdef HAVE_INTROSPECTION
+#include "compositor/meta-plugin-manager.h"
+#endif
+
+#include <glib.h>
+
+static gboolean
+print_version (const gchar    *option_name,
+               const gchar    *value,
+               gpointer        data,
+               GError        **error)
+{
+  const int latest_year = 2011;
+
+  g_print (_("mutter %s\n"
+             "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
+             "This is free software; see the source for copying conditions.\n"
+             "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
+           VERSION, latest_year);
+  exit (0);
+}
+
+static gchar *mutter_plugins;
+
+GOptionEntry mutter_options[] = {
+  {
+    "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
+    print_version,
+    N_("Print version"),
+    NULL
+  },
+  {
+    "mutter-plugins", 0, 0, G_OPTION_ARG_STRING,
+    &mutter_plugins,
+    N_("Comma-separated list of compositor plugins"),
+    "PLUGINS"
+  },
+  { NULL }
+};
+
+int
+main (int argc, char **argv)
+{
+  GOptionContext *ctx;
+  GError *error = NULL;
+
+  ctx = meta_get_option_context ();
+  g_option_context_add_main_entries (ctx, mutter_options, GETTEXT_PACKAGE);
+  if (!g_option_context_parse (ctx, &argc, &argv, &error))
+    {
+      g_printerr ("mutter: %s\n", error->message);
+      exit (1);
+    }
+
+  if (mutter_plugins)
+    {
+      MetaPluginManager *mgr;
+      char **plugins = g_strsplit (mutter_plugins, ",", -1); 
+      char **plugin;
+
+      mgr = meta_plugin_manager_get_default ();
+      for (plugin = plugins; *plugin; plugin++)
+        {
+          g_strstrip (*plugin);
+          meta_plugin_manager_load (mgr, *plugin);
+        }
+      g_strfreev (plugins);
+    }
+
+  meta_init ();
+  return meta_run ();
+}
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 3afc2c2..2530631 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -3020,12 +3020,6 @@ meta_prefs_set_no_tab_popup (gboolean whether)
 #endif
 }
 
-void
-meta_prefs_override_no_tab_popup (gboolean whether)
-{
-  no_tab_popup = whether;
-}
-
 #ifndef HAVE_GCONF
 static void
 init_button_layout(void)
diff --git a/src/include/main.h b/src/include/main.h
index b0c8dc8..23beebc 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -26,6 +26,10 @@
 
 #include <glib.h>
 
+GOptionContext *meta_get_option_context (void);
+void            meta_init               (void);
+int             meta_run                (void);
+
 typedef enum
 {
   META_EXIT_SUCCESS,
diff --git a/src/include/meta-plugin.h b/src/include/meta-plugin.h
index 36b7fbf..80d5312 100644
--- a/src/include/meta-plugin.h
+++ b/src/include/meta-plugin.h
@@ -221,6 +221,9 @@ struct _MetaPluginVersion
   }                                                                     \
 
 void
+meta_plugin_type_register (GType plugin_type);
+
+void
 meta_plugin_switch_workspace_completed (MetaPlugin *plugin);
 
 void
diff --git a/src/include/prefs.h b/src/include/prefs.h
index 2578451..f01e49b 100644
--- a/src/include/prefs.h
+++ b/src/include/prefs.h
@@ -138,7 +138,6 @@ void     meta_prefs_set_live_hidden_windows (gboolean whether);
 
 gboolean meta_prefs_get_no_tab_popup (void);
 void     meta_prefs_set_no_tab_popup (gboolean whether);
-void     meta_prefs_override_no_tab_popup (gboolean whether);
 
 /* XXX FIXME This should be x-macroed, but isn't yet because it would be
  * difficult (or perhaps impossible) to add the suffixes using the current
diff --git a/src/include/ui.h b/src/include/ui.h
index 064ca3a..2914133 100644
--- a/src/include/ui.h
+++ b/src/include/ui.h
@@ -41,7 +41,7 @@ typedef enum
   META_UI_DIRECTION_RTL
 } MetaUIDirection;
 
-void meta_ui_init (int *argc, char ***argv);
+void meta_ui_init (void);
 
 Display* meta_ui_get_display (void);
 
diff --git a/src/libmutter-wm.pc.in b/src/libmutter-wm.pc.in
new file mode 100644
index 0000000..e76d559
--- /dev/null
+++ b/src/libmutter-wm.pc.in
@@ -0,0 +1,18 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+girdir= libdir@/mutter
+typelibdir= libdir@/mutter
+
+mutter_major_version= MUTTER_MAJOR_VERSION@
+mutter_minor_version= MUTTER_MINOR_VERSION@
+mutter_micro_version= MUTTER_MICRO_VERSION@
+mutter_plugin_api_version= MUTTER_PLUGIN_API_VERSION@
+
+Name: libmutter-wm
+Description: Mutter window manager library
+Requires: gtk+-3.0 @CLUTTER_PACKAGE@ x11
+Version: @VERSION@
+Libs: -L${libdir} -lmutter-wm
+Cflags: -I${includedir}/mutter/mutter-private -DMUTTER_MAJOR_VERSION=${mutter_major_version} -DMUTTER_MINOR_VERSION=${mutter_minor_version} -DMUTTER_MICRO_VERSION=${mutter_micro_version} -DMUTTER_PLUGIN_API_VERSION=${mutter_plugin_api_version}
diff --git a/src/ui/ui.c b/src/ui/ui.c
index 4221a27..d115ae3 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -58,7 +58,7 @@ struct _MetaUI
 };
 
 void
-meta_ui_init (int *argc, char ***argv)
+meta_ui_init (void)
 {
   /* As of 2.91.7, Gdk uses XI2 by default, which conflicts with the
    * direct X calls we use - in particular, events caused by calls to
@@ -70,7 +70,7 @@ meta_ui_init (int *argc, char ***argv)
   gdk_disable_multidevice ();
 #endif
 
-  if (!gtk_init_check (argc, argv))
+  if (!gtk_init_check (NULL, NULL))
     meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
 
   meta_stock_icons_init ();



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