summaryrefslogtreecommitdiff
path: root/clutter
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2015-12-11 14:25:21 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2015-12-11 15:53:23 +0000
commit10b74e7005acc39d2b7e123ce3b81fb9b02b5afa (patch)
tree5a369785ae6846f51ba5afafea9e256c44aea8dc /clutter
parent7ca28e09746f3f1a6b240a8c1a416dd4ad6c8ff6 (diff)
downloadclutter-10b74e7005acc39d2b7e123ce3b81fb9b02b5afa.tar.gz
backend: Allow setting a list of windowing backends
Like CLUTTER_DRIVER, we want to allow users to specify a list of backends to test, and fall back to the internally defined priority as a default. This requires changing the way the allowed backend string is parsed, both for the CLUTTER_BACKEND environment variable and for the clutter_set_windowing_backend() function. Existing callers are still supported with the exact same semantics.
Diffstat (limited to 'clutter')
-rw-r--r--clutter/clutter-backend.c136
1 files changed, 93 insertions, 43 deletions
diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c
index d9ce53f1a..0d083ceaf 100644
--- a/clutter/clutter-backend.c
+++ b/clutter/clutter-backend.c
@@ -123,8 +123,6 @@ static guint backend_signals[LAST_SIGNAL] = { 0, };
static struct wl_display *_wayland_compositor_display;
#endif
-static const char *allowed_backend;
-
static void
clutter_backend_dispose (GObject *gobject)
{
@@ -532,59 +530,81 @@ clutter_backend_real_create_stage (ClutterBackend *backend,
NULL);
}
-ClutterBackend *
-_clutter_create_backend (void)
-{
- const char *backend = allowed_backend;
- ClutterBackend *retval = NULL;
-
- if (backend == NULL)
- {
- const char *backend_env = g_getenv ("CLUTTER_BACKEND");
-
- if (backend_env != NULL)
- backend = g_intern_string (backend_env);
- }
+static const char *allowed_backends;
+static const struct {
+ const char *name;
+ ClutterBackend * (* create_backend) (void);
+} available_backends[] = {
#ifdef CLUTTER_WINDOWING_OSX
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_OSX))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_OSX, NULL);
- else
+ { CLUTTER_WINDOWING_OSX, clutter_backend_osx_new },
#endif
#ifdef CLUTTER_WINDOWING_WIN32
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_WIN32))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_WIN32, NULL);
- else
+ { CLUTTER_WINDOWING_WIN32, clutter_backend_win32_new },
#endif
#ifdef CLUTTER_WINDOWING_GDK
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_GDK))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_GDK, NULL);
- else
+ { CLUTTER_WINDOWING_GDK, clutter_backend_gdk_new },
#endif
#ifdef CLUTTER_WINDOWING_X11
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_X11))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_X11, NULL);
- else
+ { CLUTTER_WINDOWING_X11, clutter_backend_x11_new },
#endif
#ifdef CLUTTER_WINDOWING_WAYLAND
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_WAYLAND))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_WAYLAND, NULL);
- else
+ { CLUTTER_WINDOWING_WAYLAND, clutter_backend_wayland_new },
#endif
#ifdef CLUTTER_WINDOWING_EGL
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_EGL))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_EGL_NATIVE, NULL);
- else
+ { CLUTTER_WINDOWING_EGL, clutter_backend_egl_native_new },
#endif
#ifdef CLUTTER_WINDOWING_MIR
- if (backend == NULL || backend == I_(CLUTTER_WINDOWING_MIR))
- retval = g_object_new (CLUTTER_TYPE_BACKEND_MIR, NULL);
- else
+ { CLUTTER_WINDOWING_MIR, clutter_backend_mir_new },
#endif
- if (backend == NULL)
+ { NULL, NULL },
+};
+
+ClutterBackend *
+_clutter_create_backend (void)
+{
+ const char *backends_list;
+ ClutterBackend *retval;
+ gboolean allow_any;
+ char **backends;
+ int i;
+
+ if (allowed_backends == NULL)
+ allowed_backends = "*";
+
+ allow_any = strstr (allowed_backends, "*") != NULL;
+
+ backends_list = g_getenv ("CLUTTER_BACKEND");
+ if (backends_list == NULL)
+ backends_list = allowed_backends;
+
+ backends = g_strsplit (backends_list, ",", 0);
+
+ retval = NULL;
+
+ for (i = 0; retval == NULL && backends[i] != NULL; i++)
+ {
+ const char *backend = backends[i];
+ gboolean is_any = g_str_equal (backend, "*");
+ int j;
+
+ for (j = 0; available_backends[j].name != NULL; j++)
+ {
+ if ((is_any && allow_any) ||
+ (is_any && strstr (allowed_backends, available_backends[j].name)) ||
+ g_str_equal (backend, available_backends[j].name))
+ {
+ retval = available_backends[j].create_backend ();
+ if (retval != NULL)
+ break;
+ }
+ }
+ }
+
+ g_strfreev (backends);
+
+ if (retval == NULL)
g_error ("No default Clutter backend found.");
- else
- g_error ("Unsupported Clutter backend: '%s'", backend);
return retval;
}
@@ -1461,10 +1481,40 @@ clutter_wayland_set_compositor_display (void *display)
/**
* clutter_set_windowing_backend:
- * @backend_type: the name of a clutter window backend
+ * @backend_type: a comma separated list of windowing backends
+ *
+ * Restricts Clutter to only use the specified backend or list of backends.
+ *
+ * You can use one of the `CLUTTER_WINDOWING_*` symbols, e.g.
+ *
+ * |[<!-- language="C" -->
+ * clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
+ * ]|
+ *
+ * Will force Clutter to use the X11 windowing and input backend, and terminate
+ * if the X11 backend could not be initialized successfully.
+ *
+ * Since Clutter 1.26, you can also use a comma-separated list of windowing
+ * system backends to provide a fallback in case backends are not available or
+ * enabled, e.g.:
+ *
+ * |[<!-- language="C" -->
+ * clutter_set_windowing_backend ("gdk,wayland,x11");
+ * ]|
+ *
+ * Will make Clutter test for the GDK, Wayland, and X11 backends in that order.
+ *
+ * You can use the `*` special value to ask Clutter to use the internally
+ * defined list of backends. For instance:
+ *
+ * |[<!-- language="C" -->
+ * clutter_set_windowing_backend ("x11,wayland,*");
+ * ]|
+ *
+ * Will make Clutter test the X11 and Wayland backends, and then fall back
+ * to the internal list of available backends.
*
- * Restricts clutter to only use the specified backend.
- * This must be called before the first API call to clutter, including
+ * This function must be called before the first API call to Clutter, including
* clutter_get_option_context()
*
* Since: 1.16
@@ -1474,7 +1524,7 @@ clutter_set_windowing_backend (const char *backend_type)
{
g_return_if_fail (backend_type != NULL);
- allowed_backend = g_intern_string (backend_type);
+ allowed_backends = g_strdup (backend_type);
}
PangoDirection