diff --git a/clutter/clutter/clutter-backend-private.h b/clutter/clutter/clutter-backend-private.h index 98bd33739..de6f00484 100644 --- a/clutter/clutter/clutter-backend-private.h +++ b/clutter/clutter/clutter-backend-private.h @@ -96,8 +96,6 @@ struct _ClutterBackendClass void (* settings_changed) (ClutterBackend *backend); }; -ClutterBackend * _clutter_create_backend (void); - ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend, ClutterStage *wrapper, GError **error); diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c index 3ad339cdf..1e41c2af7 100644 --- a/clutter/clutter/clutter-backend.c +++ b/clutter/clutter/clutter-backend.c @@ -353,8 +353,7 @@ clutter_backend_real_create_context (ClutterBackend *backend, if (internal_error != NULL) g_propagate_error (error, internal_error); else - g_set_error_literal (error, CLUTTER_INIT_ERROR, - CLUTTER_INIT_ERROR_BACKEND, + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unable to initialize the Clutter backend: no available drivers found."); return FALSE; @@ -391,28 +390,6 @@ clutter_backend_real_get_features (ClutterBackend *backend) return flags; } -static ClutterBackend * (* custom_backend_func) (void); - -void -clutter_set_custom_backend_func (ClutterBackend *(* func) (void)) -{ - custom_backend_func = func; -} - -ClutterBackend * -_clutter_create_backend (void) -{ - ClutterBackend *retval; - - g_return_val_if_fail (custom_backend_func, NULL); - - retval = custom_backend_func (); - if (!retval) - g_error ("Failed to create custom backend."); - - return retval; -} - static void clutter_backend_class_init (ClutterBackendClass *klass) { diff --git a/clutter/clutter/clutter-feature.c b/clutter/clutter/clutter-feature.c index 663d1c089..9cda1d075 100644 --- a/clutter/clutter/clutter-feature.c +++ b/clutter/clutter/clutter-feature.c @@ -70,10 +70,9 @@ clutter_features_from_cogl (void) } gboolean -_clutter_feature_init (GError **error) +clutter_feature_init (ClutterMainContext *context, + GError **error) { - ClutterMainContext *context; - CLUTTER_NOTE (MISC, "checking features"); if (!__features) @@ -86,8 +85,6 @@ _clutter_feature_init (GError **error) if (__features->features_set) return TRUE; - context = _clutter_context_get_default (); - /* makes sure we have a GL context; if we have, this is a no-op */ if (!_clutter_backend_create_context (context->backend, error)) return FALSE; diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 24dc63757..a9279d0e9 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -489,38 +489,11 @@ _clutter_context_is_initialized (void) ClutterMainContext * _clutter_context_get_default (void) { - if (G_UNLIKELY (ClutterCntx == NULL)) - { - ClutterMainContext *ctx; - - ClutterCntx = ctx = g_new0 (ClutterMainContext, 1); - - ctx->is_initialized = FALSE; - - /* create the windowing system backend */ - ctx->backend = _clutter_create_backend (); - - /* create the default settings object, and store a back pointer to - * the backend singleton - */ - ctx->settings = clutter_settings_get_default (); - _clutter_settings_set_backend (ctx->settings, ctx->backend); - - ctx->events_queue = g_async_queue_new (); - - ctx->last_repaint_id = 1; - } - + g_assert (ClutterCntx); return ClutterCntx; } -GQuark -clutter_init_error_quark (void) -{ - return g_quark_from_static_string ("clutter-init-error-quark"); -} - -static ClutterInitError +static gboolean clutter_init_real (ClutterMainContext *clutter_context, GError **error) { @@ -532,7 +505,7 @@ clutter_init_real (ClutterMainContext *clutter_context, backend = clutter_context->backend; if (!_clutter_backend_finish_init (backend, error)) - return CLUTTER_INIT_ERROR_BACKEND; + return FALSE; /* If we are displaying the regions that would get redrawn with clipped * redraws enabled we actually have to disable the clipped redrawing @@ -554,8 +527,8 @@ clutter_init_real (ClutterMainContext *clutter_context, /* this will take care of initializing Cogl's state and * query the GL machinery for features */ - if (!_clutter_feature_init (error)) - return CLUTTER_INIT_ERROR_BACKEND; + if (!clutter_feature_init (clutter_context, error)) + return FALSE; clutter_text_direction = clutter_get_text_direction (); @@ -567,9 +540,9 @@ clutter_init_real (ClutterMainContext *clutter_context, cally_accessibility_init (); /* Initialize types required for paint nodes */ - _clutter_paint_node_init_types (); + clutter_paint_node_init_types (clutter_context->backend); - return CLUTTER_INIT_SUCCESS; + return TRUE; } static void @@ -626,27 +599,57 @@ init_clutter_debug (ClutterMainContext *clutter_context) clutter_disable_mipmap_text = TRUE; } -/** - * clutter_init: (skip) - */ -ClutterInitError -clutter_init (GError **error) +ClutterContext * +clutter_context_new (ClutterBackendConstructor backend_constructor, + gpointer user_data, + GError **error) { ClutterMainContext *clutter_context; - if (clutter_is_initialized) - return CLUTTER_INIT_SUCCESS; + if (ClutterCntx) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Currently only creating one clutter context is supported"); + return NULL; + } - clutter_base_init (); - - clutter_context = _clutter_context_get_default (); + clutter_graphene_init (); + clutter_context = g_new0 (ClutterMainContext, 1); init_clutter_debug (clutter_context); - clutter_context->frame_rate = clutter_default_fps; clutter_context->show_fps = clutter_show_fps; + clutter_context->is_initialized = FALSE; - return clutter_init_real (clutter_context, error); + clutter_context->backend = backend_constructor (user_data); + clutter_context->settings = clutter_settings_get_default (); + _clutter_settings_set_backend (clutter_context->settings, + clutter_context->backend); + + clutter_context->events_queue = g_async_queue_new (); + clutter_context->last_repaint_id = 1; + + if (!clutter_init_real (clutter_context, error)) + return NULL; + + ClutterCntx = clutter_context; + + return clutter_context; +} + +void +clutter_context_free (ClutterMainContext *clutter_context) +{ + g_clear_pointer (&clutter_context->events_queue, g_async_queue_unref); + g_clear_pointer (&clutter_context->backend, clutter_backend_destroy); + ClutterCntx = NULL; + g_free (clutter_context); +} + +ClutterBackend * +clutter_context_get_backend (ClutterContext *clutter_context) +{ + return clutter_context->backend; } gboolean @@ -1506,24 +1509,6 @@ _clutter_process_event (ClutterEvent *event) context->current_event = g_slist_delete_link (context->current_event, context->current_event); } -void -clutter_base_init (void) -{ - static gboolean initialised = FALSE; - - if (!initialised) - { - initialised = TRUE; - -#if !GLIB_CHECK_VERSION (2, 35, 1) - /* initialise GLib type system */ - g_type_init (); -#endif - - clutter_graphene_init (); - } -} - /** * clutter_get_default_frame_rate: * diff --git a/clutter/clutter/clutter-main.h b/clutter/clutter/clutter-main.h index 576ecf74c..b7f8789ab 100644 --- a/clutter/clutter/clutter-main.h +++ b/clutter/clutter/clutter-main.h @@ -77,37 +77,6 @@ typedef enum CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME = 1 << 10, } ClutterDrawDebugFlag; -/** - * CLUTTER_INIT_ERROR: - * - * #GError domain for #ClutterInitError - */ -#define CLUTTER_INIT_ERROR (clutter_init_error_quark ()) - -/** - * ClutterInitError: - * @CLUTTER_INIT_SUCCESS: Initialisation successful - * @CLUTTER_INIT_ERROR_UNKNOWN: Unknown error - * @CLUTTER_INIT_ERROR_THREADS: Thread initialisation failed - * @CLUTTER_INIT_ERROR_BACKEND: Backend initialisation failed - * @CLUTTER_INIT_ERROR_INTERNAL: Internal error - * - * Error conditions returned by clutter_init(). - * - * Since: 0.2 - */ -typedef enum -{ - CLUTTER_INIT_SUCCESS = 1, - CLUTTER_INIT_ERROR_UNKNOWN = 0, - CLUTTER_INIT_ERROR_THREADS = -1, - CLUTTER_INIT_ERROR_BACKEND = -2, - CLUTTER_INIT_ERROR_INTERNAL = -3 -} ClutterInitError; - -CLUTTER_EXPORT -GQuark clutter_init_error_quark (void); - /** * CLUTTER_PRIORITY_REDRAW: * @@ -121,17 +90,6 @@ GQuark clutter_init_error_quark (void); */ #define CLUTTER_PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 50) -/* Initialisation */ -CLUTTER_EXPORT -void clutter_base_init (void); -CLUTTER_EXPORT -ClutterInitError clutter_init (GError **error) G_GNUC_WARN_UNUSED_RESULT; - -CLUTTER_EXPORT -GOptionGroup * clutter_get_option_group (void); -CLUTTER_EXPORT -GOptionGroup * clutter_get_option_group_without_init (void); - CLUTTER_EXPORT void clutter_do_event (ClutterEvent *event); diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h index 818a48bb9..1b5d21679 100644 --- a/clutter/clutter/clutter-mutter.h +++ b/clutter/clutter/clutter-mutter.h @@ -38,6 +38,32 @@ #include "clutter-stage-view-private.h" #include "clutter.h" +typedef struct _ClutterMainContext ClutterContext; + +typedef ClutterBackend * (* ClutterBackendConstructor) (gpointer user_data); + +/** + * clutter_context_new: (skip) + */ +CLUTTER_EXPORT +ClutterContext * clutter_context_new (ClutterBackendConstructor backend_constructor, + gpointer user_data, + GError **error); + +/** + * clutter_context_free: (skip) + */ +CLUTTER_EXPORT +void clutter_context_free (ClutterContext *clutter_context); + +/** + * clutter_context_get_backend: + * + * Returns: (transfer none): The corresponding %ClutterBackend + */ +CLUTTER_EXPORT +ClutterBackend * clutter_context_get_backend (ClutterContext *clutter_context); + CLUTTER_EXPORT GList * clutter_stage_peek_stage_views (ClutterStage *stage); @@ -45,9 +71,6 @@ CLUTTER_EXPORT gboolean clutter_actor_is_effectively_on_stage_view (ClutterActor *self, ClutterStageView *view); -CLUTTER_EXPORT -void clutter_set_custom_backend_func (ClutterBackend *(* func) (void)); - CLUTTER_EXPORT int64_t clutter_stage_get_frame_counter (ClutterStage *stage); diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h index b084e81d4..c10f10f7e 100644 --- a/clutter/clutter/clutter-paint-node-private.h +++ b/clutter/clutter/clutter-paint-node-private.h @@ -27,6 +27,7 @@ #include <glib-object.h> #include <json-glib/json-glib.h> +#include <clutter/clutter-backend.h> #include <clutter/clutter-paint-context.h> #include <clutter/clutter-paint-node.h> @@ -109,7 +110,7 @@ void _clutter_paint_operation_paint_path (const C void _clutter_paint_operation_clip_path (const ClutterPaintOperation *op); void _clutter_paint_operation_paint_primitive (const ClutterPaintOperation *op); -void _clutter_paint_node_init_types (void); +void clutter_paint_node_init_types (ClutterBackend *clutter_backend); gpointer _clutter_paint_node_create (GType gtype); ClutterPaintNode * _clutter_transform_node_new (const graphene_matrix_t *matrix); diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c index 8ca509988..2b5ed9971 100644 --- a/clutter/clutter/clutter-paint-nodes.c +++ b/clutter/clutter/clutter-paint-nodes.c @@ -51,30 +51,30 @@ static CoglPipeline *default_color_pipeline = NULL; static CoglPipeline *default_texture_pipeline = NULL; /*< private > - * _clutter_paint_node_init_types: + * clutter_paint_node_init_types: * * Initializes the required types for ClutterPaintNode subclasses */ void -_clutter_paint_node_init_types (void) +clutter_paint_node_init_types (ClutterBackend *clutter_backend) { - CoglContext *ctx; + CoglContext *cogl_context; CoglColor cogl_color; GType node_type G_GNUC_UNUSED; if (G_LIKELY (default_color_pipeline != NULL)) return; - ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + cogl_context = clutter_backend_get_cogl_context (clutter_backend); node_type = clutter_paint_node_get_type (); cogl_color_init_from_4f (&cogl_color, 1.0, 1.0, 1.0, 1.0); - default_color_pipeline = cogl_pipeline_new (ctx); + default_color_pipeline = cogl_pipeline_new (cogl_context); cogl_pipeline_set_color (default_color_pipeline, &cogl_color); - default_texture_pipeline = cogl_pipeline_new (ctx); + default_texture_pipeline = cogl_pipeline_new (cogl_context); cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0); cogl_pipeline_set_color (default_texture_pipeline, &cogl_color); cogl_pipeline_set_layer_wrap_mode (default_texture_pipeline, 0, diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h index ab4d5aa84..15dba0bb5 100644 --- a/clutter/clutter/clutter-private.h +++ b/clutter/clutter/clutter-private.h @@ -154,7 +154,6 @@ struct _ClutterMainContext /* boolean flags */ guint is_initialized : 1; - guint options_parsed : 1; guint show_fps : 1; }; @@ -176,7 +175,8 @@ CLUTTER_EXPORT gboolean _clutter_context_is_initialized (void); gboolean _clutter_context_get_show_fps (void); -gboolean _clutter_feature_init (GError **error); +gboolean clutter_feature_init (ClutterMainContext *clutter_context, + GError **error); /* Diagnostic mode */ gboolean _clutter_diagnostic_enabled (void); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 9489f3067..234053a6f 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -162,7 +162,7 @@ struct _MetaBackendPrivate WacomDeviceDatabase *wacom_db; #endif - ClutterBackend *clutter_backend; + ClutterContext *clutter_context; ClutterSeat *default_seat; ClutterActor *stage; @@ -257,7 +257,7 @@ meta_backend_dispose (GObject *object) g_clear_pointer (&priv->stage, clutter_actor_destroy); g_clear_pointer (&priv->idle_manager, meta_idle_manager_free); g_clear_object (&priv->renderer); - g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy); + g_clear_pointer (&priv->clutter_context, clutter_context_free); g_clear_list (&priv->gpus, g_object_unref); G_OBJECT_CLASS (meta_backend_parent_class)->dispose (object); @@ -1037,11 +1037,11 @@ static GSourceFuncs clutter_source_funcs = { }; static ClutterBackend * -meta_get_clutter_backend (void) +meta_clutter_backend_constructor (gpointer user_data) { - MetaBackend *backend = meta_get_backend (); + MetaBackend *backend = META_BACKEND (user_data); - return meta_backend_get_clutter_backend (backend); + return META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend); } static ClutterSeat * @@ -1059,9 +1059,10 @@ init_clutter (MetaBackend *backend, MetaBackendSource *backend_source; GSource *source; - clutter_set_custom_backend_func (meta_get_clutter_backend); - - if (clutter_init (error) != CLUTTER_INIT_SUCCESS) + priv->clutter_context = clutter_context_new (meta_clutter_backend_constructor, + backend, + error); + if (!priv->clutter_context) return FALSE; priv->default_seat = meta_backend_create_default_seat (backend, error); @@ -1526,14 +1527,13 @@ ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend) { MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + ClutterContext *clutter_context; - if (!priv->clutter_backend) - { - priv->clutter_backend = - META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend); - } + clutter_context = priv->clutter_context; + if (!clutter_context) + return NULL; - return priv->clutter_backend; + return clutter_context_get_backend (clutter_context); } void diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index eb6771b80..bc378fb19 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -485,7 +485,11 @@ cogl_context_from_renderer_native (MetaRendererNative *renderer_native) { MetaRenderer *renderer = META_RENDERER (renderer_native); MetaBackend *backend = meta_renderer_get_backend (renderer); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterBackend *clutter_backend; + + clutter_backend = meta_backend_get_clutter_backend (backend); + if (!clutter_backend) + return NULL; return clutter_backend_get_cogl_context (clutter_backend); } diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index 92f9dbd74..80efb6e41 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -867,7 +867,6 @@ meta_backend_x11_initable_init (GInitable *initable, priv->xdisplay = xdisplay; priv->xcb = XGetXCBConnection (priv->xdisplay); - meta_clutter_x11_set_display (xdisplay); init_xkb_state (x11); diff --git a/src/backends/x11/meta-clutter-backend-x11.c b/src/backends/x11/meta-clutter-backend-x11.c index 501ae8b32..6ea57da8a 100644 --- a/src/backends/x11/meta-clutter-backend-x11.c +++ b/src/backends/x11/meta-clutter-backend-x11.c @@ -28,6 +28,7 @@ #include "backends/meta-backend-private.h" #include "backends/meta-renderer.h" +#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-clutter-backend-x11.h" #include "backends/x11/meta-keymap-x11.h" #include "backends/x11/meta-seat-x11.h" @@ -76,7 +77,6 @@ static const gchar *atom_names[] = { /* various flags corresponding to pre init setup calls */ static gboolean clutter_enable_stereo = FALSE; -static Display *_foreign_dpy = NULL; /* options */ static gboolean clutter_synchronise = FALSE; @@ -117,47 +117,13 @@ meta_clutter_backend_x11_finish_init (ClutterBackend *clutter_backend, { MetaClutterBackendX11 *clutter_backend_x11 = META_CLUTTER_BACKEND_X11 (clutter_backend); + MetaClutterBackendX11Private *priv = + meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); + MetaBackendX11 *backend_x11 = META_BACKEND_X11 (priv->backend); Atom atoms[N_ATOM_NAMES]; Screen *xscreen; - if (_foreign_dpy) - backend_x11->xdisplay = _foreign_dpy; - - /* Only open connection if not already set by prior call to - * clutter_x11_set_display() - */ - if (clutter_backend_x11->xdisplay == NULL) - { - const char *display_name; - - display_name = g_getenv ("DISPLAY"); - if (display_name && *display_name != '\0') - { - g_debug ("XOpenDisplay on '%s'", display_name); - - clutter_backend_x11->xdisplay = XOpenDisplay (display_name); - if (clutter_backend_x11->xdisplay == NULL) - { - g_set_error (error, CLUTTER_INIT_ERROR, - CLUTTER_INIT_ERROR_BACKEND, - "Unable to open display '%s'", - display_name); - return FALSE; - } - } - else - { - g_set_error_literal (error, CLUTTER_INIT_ERROR, - CLUTTER_INIT_ERROR_BACKEND, - "Unable to open display. You have to set the " - "DISPLAY environment variable, or use the " - "--display command line argument"); - return FALSE; - } - } - - - g_debug ("Getting the X screen"); + clutter_backend_x11->xdisplay = meta_backend_x11_get_xdisplay (backend_x11); /* add event filter for Cogl events */ meta_clutter_backend_x11_add_filter (clutter_backend_x11, @@ -297,8 +263,7 @@ check_onscreen_template (CoglRenderer *renderer, } else { - g_set_error_literal (error, CLUTTER_INIT_ERROR, - CLUTTER_INIT_ERROR_BACKEND, + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, internal_error != NULL ? internal_error->message : "Creation of a CoglDisplay failed"); @@ -543,19 +508,6 @@ meta_clutter_x11_get_default_display (void) return META_CLUTTER_BACKEND_X11 (clutter_backend)->xdisplay; } -void -meta_clutter_x11_set_display (Display *xdisplay) -{ - if (_clutter_context_is_initialized ()) - { - g_warning ("%s() can only be used before calling clutter_init()", - G_STRFUNC); - return; - } - - _foreign_dpy= xdisplay; -} - int meta_clutter_x11_get_default_screen (void) { diff --git a/src/backends/x11/meta-clutter-backend-x11.h b/src/backends/x11/meta-clutter-backend-x11.h index 50b8434b0..9e1cfca13 100644 --- a/src/backends/x11/meta-clutter-backend-x11.h +++ b/src/backends/x11/meta-clutter-backend-x11.h @@ -82,7 +82,6 @@ gint meta_clutter_x11_untrap_x_errors (void); Display *meta_clutter_x11_get_default_display (void); int meta_clutter_x11_get_default_screen (void); Window meta_clutter_x11_get_root_window (void); -void meta_clutter_x11_set_display (Display * xdpy); void meta_clutter_backend_x11_add_filter (MetaClutterBackendX11 *clutter_backend_x11, MetaX11FilterFunc func, diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c index e31faff53..0ee74e31b 100644 --- a/src/backends/x11/meta-renderer-x11.c +++ b/src/backends/x11/meta-renderer-x11.c @@ -30,6 +30,7 @@ #include "backends/meta-logical-monitor.h" #include "backends/meta-renderer-view.h" #include "backends/meta-renderer.h" +#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-clutter-backend-x11.h" #include "backends/x11/meta-renderer-x11.h" #include "cogl/cogl-xlib.h" @@ -81,8 +82,10 @@ get_x11_cogl_winsys_vtable (CoglRenderer *renderer) static CoglRenderer * meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer) { + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); CoglRenderer *cogl_renderer; - Display *xdisplay = meta_clutter_x11_get_default_display (); cogl_renderer = cogl_renderer_new (); cogl_renderer_set_custom_winsys (cogl_renderer, get_x11_cogl_winsys_vtable,